字符串(string.cpp)
阿新 • • 發佈:2018-10-16
fin line 矩陣 每次 cdc fine 思路 include 設置
字符串(string.cpp)
神TM字符串DP
題目描述:
小林和亮亮正在做一個遊戲。小林隨意的寫出一個字符串,字符串僅由大寫字母組成,然後指定一個非負整數m,亮亮可以進行至多m次操作。每次操作為交換相鄰的兩個字符。亮亮的目標是使得操作後的字符串出現最長相同的字符的長度最大。你的任務是計算這個最大長度是多少。
樣例輸入:
ABCCDCDDC
4
樣例輸出:
4
思路:
設置一個字符串長度x26大小的二維數組,對於字符串中的每個字母,記錄其出現的位置,將對應的矩陣元素設置為1,其余元素為0,然後按列優先遍歷矩陣,將每個字母出現的位置下標記錄到一個數組裏,計算將i和j之間的相同元素全部移動到一起需要的最小移動次數,在這個最小次數滿足滿足約束條件的前提下,篩選出最大的連續字母的個數。最後比較所有字母的最大連續個數,輸出其中的最大值即可。
CODE:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #define N 26 #define M 5050 using namespace std; string s; int a[M][N],m;//a是矩陣,出現字母的地方都置1 int f[M],num[M]; //f[i]是存放各字母在滿足約束的情況下最大的連續數 int dp(int i , int j , int*a) { if(i == j) return 0; else if(i + 1 == j) return a[j] - a[i] - 1; else return dp(i + 1 , j - 1 , a) + a[j] - a[i] - (j - i); } inline void init() { memset(a,0,sizeof(a) ); memset(f,0,sizeof(f) ); memset(num,0,sizeof(num) ); } inline void open_judge() { freopen("string.in","r",stdin); freopen("string.out","w",stdout); } int main() { //open_judge(); cin>>s; scanf("%d",&m); init(); int len = s.length(); for(int i = 0 ; i < len ; i++) { for(int j = 0 ; j < 26 ; j++) { a[i][s[i] - 'A'] = 1; } } for(int j = 0 ; j < 26 ; j++) { int k = 0; for(int i = 0 ; i < len;i++) { if(a[i][j] == 1) num[k++] = i; } if(k == 1) f[j] = 1; else { int temp = -1; for(int i = 0 ; i < k ; i++) { for(int l = i + 1 ; l < k ; l++) { if( dp(i , l , num) <= m ) { if((l - i) + 1 > temp) temp = (l - i) + 1; } } } f[j] = temp; } } sort(f , f + N); printf("%d\n",f[N-1]); return 0; }
字符串(string.cpp)