bzoj1090: [SCOI2003]字符串折叠 区间dp+hash
2017-12-31 13:27
337 查看
题目大意:一个重复k次的子串x可以折叠替换成k(x)的形式,问原串经折叠后的最短长度.n≤100<
4000
/span>.
k(x)的长度为 k的位数+x的长度+2.
区间dp,转移方程为f[i][j]=min(j−i+1,f[i][k]+f[k+1][j])
如果i~j的子串可以由i~i+k-1的子串重复得来
就要再转移f[i][j]=min(f[i][j],f[i][i+k−1]+d[len/k]+2)
d[i]表示数字i的长度.
用hash判断两个子串是否相同。
另外这里判断的时候,不需要判断len/k次,
只需要判i~j-k和j-k+1~j是否相同即可。
4000
/span>.
k(x)的长度为 k的位数+x的长度+2.
区间dp,转移方程为f[i][j]=min(j−i+1,f[i][k]+f[k+1][j])
如果i~j的子串可以由i~i+k-1的子串重复得来
就要再转移f[i][j]=min(f[i][j],f[i][i+k−1]+d[len/k]+2)
d[i]表示数字i的长度.
用hash判断两个子串是否相同。
另外这里判断的时候,不需要判断len/k次,
只需要判i~j-k和j-k+1~j是否相同即可。
#include <bits/stdc++.h> #define ull unsigned long long #define clr(x,i) memset(x,i,sizeof(x)) using namespace std; const int N=105; const ull seed=131; char str ; int n,a ,d ,f ; ull h ,pw ; void solve() { clr(f,60); for(int i=1;i<=n;i++) f[i][i]=1; for(int len=2;len<=n;len++) for(int i=1;i+len-1<=n;i++) { int j=i+len-1; for(int k=i;k<j;k++) f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]); for(int k=1;i+k-1<=j;k++) if(len%k==0) { ull h1=h[j-k]-h[i-1]*pw[len-k];//i~(j-k) ull h2=h[j]-h[i+k-1]*pw[len-k];//(i+k-1)~j if(h1==h2) f[i][j]=min(f[i][j],f[i][i+k-1]+d[len/k]+2); } } printf("%d\n",f[1] ); } void init() { pw[0]=1; for(int i=1;i<=n;i++)pw[i]=pw[i-1]*seed; for(int i=1;i<=n;i++) a[i]=str[i]-'a'+1; for(int i=1;i<=n;i++) h[i]=h[i-1]*seed+a[i]; for(int i=1;i<=n;i++) d[i]=(i/10)+1; } int main() { scanf("%s",str+1);n=strlen(str+1); init(); solve(); return 0; }
相关文章推荐
- bzoj1090[SCOI2003]字符串折叠
- 【BZOJ】1090: [SCOI2003]字符串折叠(dp)
- 【BZOJ 1090】[SCOI2003]字符串折叠
- [BZOJ 1090][SCOI 2003]字符串折叠(DP)
- BZOJ 1090 [SCOI2003]字符串折叠 区间DP
- 【BZOJ1090 || SCOI2003】字符串折叠
- BZOJ 1090: [SCOI2003]字符串折叠 区间动归
- BZOJ 1090: [SCOI2003]字符串折叠 区间DP
- [bzoj1090][SCOI2003]字符串折叠_区间dp
- [DP] BZOJ1090: [SCOI2003]字符串折叠
- BZOJ 1090: [SCOI2003]字符串折叠|动态规划
- bzoj 1090 [SCOI2003]字符串折叠(区间DP)
- 【BZOJ1090】[SCOI2003]字符串折叠【区间DP】
- BZOJ1090: [SCOI2003]字符串折叠
- 【bzoj1090】[SCOI2003]字符串折叠
- [BZOJ]1090: [SCOI2003]字符串折叠 区间DP
- bzoj1090 [SCOI2003]字符串折叠
- bzoj 1090 [SCOI2003]字符串折叠
- BZOJ 1090[SCOI2003]字符串折叠 | 区间DP
- bzoj1090 [SCOI2003]字符串折叠(区间dp+Hash)