先上題目:express
Passing time, walking the passage, as you pass the String Parsing Department(abbreviated SPaDe), you pause, amazed at them by parsing strings way past midnight. At the SPaDe , they are overwhelmed with the stringent requirements to compression recently introduced by the SPaDe's director, Dr. Spade. Any string longer than 4 characters must now be compressed as much as possible, Dr. Spade dictates! "If a string can be expressed shorter, so it must be!", he shouts.ide
He then yells that abababab can be expressed as just(ab)4 which is only 5 symbols, a whole saving of 3 symbols, and everyone in the Department breaks out in a song of celebration, chanting:優化
This is why I'm hot This is why I'm hot This is why This is why This is why I'm hot This is why I'm hot This is why I'm hot This is why This is why This is why I'm hot
but of course given in its compressed formui
(This is why I'm hot)2 (This is why)2 (This is why I'm hot)3 (This is why)3 I'm hot
Given a string S over the alphabet {a,b,c,d} as input, output the length of its most compressed version. The SPaDe has yet to discover nested compression as in ((a)2b)3 so use only one-level compressionspa
The first line contains an integer T (1 <= T <= 100), the number of test cases. For each test case there is a line with a string S (5 <= |S| <= 100).code
For each test case, print on a separate line the minimum length of S after the compression described above.orm
2 abcda dabbaabbabadddddccccbbbbbbbbbbbb
5 23
The string from the second example can be compressed into d(abba)2ba(d)5cccc(b)12 .blog
題意:給出一個一個串,將其壓縮,要求壓縮的部分是其循環節,用一對括號括住而且在後面跟上循環次數的數字,不能嵌套壓縮,問要因此後的字符串最短有多短(有可能不須要壓縮)。rem
區間dp+KMP求循環節。字符串
原始作法dp[i][j]表示第i~j位的字符壓縮之後須要最少須要多少長度來保存。而後對於第i~第j位的字符串還須要求一次循環節。這樣的時間複雜度是O(n^3)算上100組case的話勉強能夠在1s跑完。其實這就是正解了。可是比賽的時候小夥伴以爲可能會TLE,因此優化了一下變成dp[i]=min{dp[k]+(k+1,i)},枚舉k。中途WA了一次,緣由是get_next寫的和正常的有點不同,因此快要被小夥伴暴打一頓了→_→。
上代碼:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #define MAX 102 6 #define INF (1<<30) 7 using namespace std; 8 9 char s[MAX]; 10 int Next[MAX]; 11 int ne[MAX]; 12 int dp[MAX]; 13 14 void get_next(char* c,int len,int* next){ 15 int k,i; 16 k=-1;i=0; 17 next[0]=-1; 18 while(i<=len){ 19 if(k==-1 || c[i]==c[k]){ 20 k++; i++; next[i]=k; 21 }else{ 22 k=next[k]; 23 } 24 } 25 } 26 27 inline int getVal(int x){ 28 int ans=0; 29 while(x){ 30 ans++; 31 x/=10; 32 } 33 return ans; 34 } 35 36 int main(){ 37 //freopen("in_a.txt","r",stdin); 38 int t,l,m,e,u,v; 39 scanf("%d",&t); 40 while(t--){ 41 scanf("%s",s); 42 int len=strlen(s); 43 get_next(s,len,Next); 44 for(int i=0;i<len;i++){ 45 46 dp[i]=i-0+1; 47 if((i+1)%(i+1-Next[i+1])==0){ 48 m=(i+1)/(i+1-Next[i+1]); 49 l=2+(i+1-Next[i+1])+getVal(m); 50 }else l=INF; 51 dp[i]=min(l,dp[i]); 52 53 for(int j=0;j<i;j++){ 54 get_next(s+j+1,i-j,ne); 55 v=i-j; 56 if((i-j)%(i-j-ne[i-j])==0){ 57 e=(i-j)/(i-j-ne[i-j]); 58 u=2+(i-j-ne[i-j])+getVal(e); 59 }else u=INF; 60 v=min(u,v); 61 dp[i]=min(dp[i],dp[j]+v); 62 } 63 } 64 printf("%d\n",dp[len-1]); 65 } 66 return 0; 67 }