区间DP+next求循环节 uva 6876

 1 // 区间DP+next求循环节 uva 6876
 2 // 题意:化简字符串 并表示出来
 3 // 思路:dp[i][j]表示 i到j的最小长度
 4 // 分成两部分 再求一个循环节
 5 
 6 #include <iostream>
 7 #include <algorithm>
 8 #include <cstring>
 9 #include <cstdio>
10 #include <vector>
11 #include <cmath>
12 #include <map>
13 #include <queue>
14 using namespace std;
15 #define LL long long
16 typedef pair<int,int> pii;
17 const int inf = 0x3f3f3f3f;
18 const int MOD = 998244353;
19 const int N = 1020;
20 const int maxx = 200010; 
21 #define clc(a,b) memset(a,b,sizeof(a))
22 const double eps = 0.025;
23 void fre() {freopen("in.txt","r",stdin);}
24 void freout() {freopen("out.txt","w",stdout);}
25 inline int read() {int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();}while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
26 
27 char s[N];
28 int dp[N][N];
29 int cas=1;
30 int nextt[N];
31 
32 int getnext(char *t,int len){
33     int i=0,j=-1;
34     // int len=strlen(t);
35     nextt[0]=-1;
36     while(i<len){
37         if(t[i]==t[j]||j==-1){
38             i++;
39             j++;
40             nextt[i]=j;
41         }
42         else
43             j=nextt[j];
44     }
45     return len-nextt[len];
46 }
47 
48 int getbit(int x){
49     int cnt=0;
50     while(x){
51         x/=10;
52         cnt++;
53     }
54     return cnt;
55 }
56 void DP(){
57     int n=strlen(s+1);
58     for(int i=1;i<=n;i++) {
59         for(int j=i+1;j<=n;j++)
60            dp[i][j]=1010;
61         dp[i][i]=1;
62     }
63     for(int len=2;len<=n;len++){
64         for(int l=1;l+len-1<=n;l++){
65             int r=l+len-1;
66             for(int k=l;k<r;k++){
67                 dp[l][r]=min(dp[l][k]+dp[k+1][r],dp[l][r]);
68             }
69             int t=getnext(s+l,len);
70             if((len%t)==0){
71                 int tem=dp[l][l+t-1];
72                 if(t>1) tem+=2;
73                 tem+=getbit(len/t);
74                 dp[l][r]=min(dp[l][r],tem);
75             }
76         }
77     }
78     printf("Case %d: %d\n",cas++,dp[1][n]);
79 }
80 int main(){
81     // fre();
82     while(~scanf("%s",s+1)){
83         if(s[1]=='0') break;
84         DP();
85     }
86     return 0;
87 }

 

posted @ 2016-09-16 11:22  yyblues  阅读(281)  评论(0编辑  收藏  举报