BZOJ 1090: [SCOI2003]字符串折叠 区间DP
1090: [SCOI2003]字符串折叠
Time Limit: 1 Sec
Memory Limit: 256 MB
题目连接
http://www.lydsy.com/JudgeOnline/problem.php?id=1090Description
折叠的定义如下: 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
题意
题解:
哎呦卧槽,这道题和http://www.cnblogs.com/qscqesze/p/4782156.html这道题一模一样……
双倍经验爽呀!
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <bitset> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 110000 #define mod 10007 #define eps 1e-9 #define pi 3.1415926 int Num; //const int inf=0x7fffffff; //§ß§é§à§é¨f§³ const ll Inf=0x3f3f3f3f3f3f3f3fll; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } //************************************************************************************** string s[110][110]; int n; int dp[110][110]; int vis[110][110]; char S[110]; int FF(int x) { int add=0; while(x) { add++; x/=10; } return add; } string F(int x) { string ss; while(x) { ss+=(char)(x%10+'0'); x/=10; } reverse(ss.begin(),ss.end()); return ss; } int solve(int l,int r) { if(vis[l][r])return dp[l][r]; vis[l][r]=1; for(int i=l;i<r;i++) { if(dp[l][r]>solve(l,i)+solve(i+1,r)) { dp[l][r]=dp[l][i]+dp[i+1][r]; s[l][r]=s[l][i]+s[i+1][r]; } } for(int i=1;i<r-l+1;i++) { if((r-l+1)%(i)!=0) continue; int add = 0; for(int k=0;;k++) { if((k+1)*i>r-l+1) break; for(int j=0;j<i;j++) { if(S[l+k*i+j]!=S[l+j]) break; if(j==i-1) add+=1; } } if(add==(r-l+1)/i) { int point=solve(l,l+i-1)+2+FF(add); if(dp[l][r]>point) { dp[l][r]=point; s[l][r]=""; s[l][r]+=F(add)+'('; s[l][r]+=s[l][(1)*i-1+l]; s[l][r]+=')'; } } } return dp[l][r]; } int main() { scanf("%s",S+1); n = strlen(S+1); for(int i=1;i<=n;i++) { for(int j=i;j<=n;j++) { dp[i][j]=j-i+1; for(int k=0;k<j-i+1;k++) { s[i][j]+=S[i+k]; } } } solve(1,n); cout<<dp[1][n]<<endl; return 0; }