【bzoj1090】 [SCOI2003]字符串折叠
Description
折叠的定义如下: 1. 一个字符串可以看成它自身的折叠。记作S S 2. X(S)是X(X>1)个S连接在一起的串的折叠。记作X(S) SSSS…S(X个S)。 3. 如果A A’, BB’,则AB A’B’ 例如,因为3(A) = AAA, 2(B) = BB,所以3(A)C2(B) AAACBB,而2(3(A)C)2(B)AAACAAACBB 给一个字符串,求它的最短折叠。例如AAAAAAAAAABABABCCD的最短折叠为:9(A)3(AB)CCD。
Input
仅一行,即字符串S,长度保证不超过100。
Output
仅一行,即最短的折叠长度。
Sample Input
NEERCYESYESYESNEERCYESYESYES
Sample Output
14
HINT
一个最短的折叠为:2(NEERC3(YES))
区间动规。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<cstdlib> 7 #include<vector> 8 using namespace std; 9 typedef long long ll; 10 typedef long double ld; 11 typedef pair<int,int> pr; 12 const double pi=acos(-1); 13 #define rep(i,a,n) for(int i=a;i<=n;i++) 14 #define per(i,n,a) for(int i=n;i>=a;i--) 15 #define Rep(i,u) for(int i=head[u];i;i=Next[i]) 16 #define clr(a) memset(a,0,sizeof(a)) 17 #define pb push_back 18 #define mp make_pair 19 #define fi first 20 #define sc second 21 #define pq priority_queue 22 #define pqb priority_queue <int, vector<int>, less<int> > 23 #define pqs priority_queue <int, vector<int>, greater<int> > 24 #define vec vector 25 ld eps=1e-9; 26 ll pp=1000000007; 27 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;} 28 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;} 29 void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); } 30 //void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; } 31 int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1}; 32 ll read(){ ll ans=0; char last=' ',ch=getchar(); 33 while(ch<'0' || ch>'9')last=ch,ch=getchar(); 34 while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar(); 35 if(last=='-')ans=-ans; return ans; 36 } 37 char ch[200]; 38 int dp[200][200]; 39 inline int calc(int n){ 40 int num=0; 41 while (n) { n/=10; num++; } 42 return num; 43 } 44 inline int pd(int i,int k,int j){ 45 if ((k-i+1)>(j-k+1)) return 0; 46 if ((j-i+1)%(k-i+1)!=0) return 0; 47 for (int t=k+1;t<=j;t++){ 48 if (ch[t]!=ch[(t-i)%(k-i+1)+i]) return 0; 49 } 50 return 1; 51 } 52 int main(){ 53 scanf("%s",ch+1); int n=strlen(ch+1); 54 for (int p=1;p<=n;p++){ 55 for (int i=1;i<=n;i++){ 56 int j=i+p-1; 57 if (j>n) continue; 58 dp[i][j]=j-i+1; 59 for (int k=i;k<j;k++){ 60 if (pd(i,k,j)) dp[i][j]=min(dp[i][j],dp[i][k]+2+calc((j-i+1)/(k-i+1))); 61 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); 62 } 63 } 64 } 65 printf("%d",dp[1][n]); 66 return 0; 67 }