[bzoj1090][SCOI2003]字符串折叠_区间dp

字符串折叠 bzoj-1090 SCOI-2003

题目大意:我说不明白...链接

注释:自己看

想法:动态规划

状态:dp[i][j]表示从第i个字符到第j个字符折叠后的最短长度。

转移:dp[l][r]=min(r-l+1,dp[l][k]+dp[k+1][r])

当k+1~r可以有l~k得到时还要

dp[l][r]=min(dp[l][r],dp[l][k]+2+calc((r-l+1)/(k-l+1)));//calc用来计算一个十进制数所占位数

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char s[101];
int f[101][101];
bool mark[101][101];
bool jud(int l,int r,int cl,int cr)
{
if((r-l+1)%(cr-cl+1)!=0)return false;
for(int i=l;i<=r;i++)
if(s[i]!=s[(i-l)%(cr-cl+1)+cl])return false;
return true;
}
int get(int x)
{
int t=0;
while(x)
{
x/=10;t++;
}
return t;
}
int dp(int l,int r)
{
if(l==r)return 1;
if(mark[l][r])return f[l][r];
mark[l][r]=1;
int t=r-l+1;
for(int i=l;i<r;i++)
{
t=min(t,dp(l,i)+dp(i+1,r));
if(jud(i+1,r,l,i))
t=min(t,dp(l,i)+2+get((r-i)/(i-l+1)+1));
}
return f[l][r]=t;
}
int main()
{
scanf("%s",s);
printf("%d",dp(0,strlen(s)-1));
return 0;
}

小结:好题,就是那个十进制的太不要脸了.......

上一篇:**php队列的实现思路和详细过程


下一篇:Android实现Material Design风格的设置页面(滑动开关控件)