P2400 秘密文件(区间dp)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2400 秘密文件(区间dp)相关的知识,希望对你有一定的参考价值。
P2400 秘密文件(区间dp)
两个相邻的缩短串拼接后仍然是缩短串。
本身是周期串也可以缩短。
不难发现是区间dp。
- 拼接缩短
- 自身缩短
输出答案维护 a n s ( i , j ) ans(i,j) ans(i,j)数组即可
// Problem: P4302 [SCOI2003]字符串折叠
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4302
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-02-26 16:48:06
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=105,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
void Print(int *a,int n)
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
char a[N];
int f[N][N],n;
string ans[N][N];
bool check(char *a,int n,int l)
for(int i=l;i<n;i++)
if(a[i]!=a[i%l]) return false;
return true;
int num[N];
int main()
for(int i=1;i<10;i++) num[i]=1;
for(int i=10;i<100;i++) num[i]=2;
num[100]=3;
while(~scanf("%s",a+1))
int n=strlen(a+1);
mst(f,0x3f);
for(int i=1;i<=n;i++) f[i][i]=1,ans[i][i]=a[i];
for(int l=2;l<=n;l++)
for(int i=1,j=l;j<=n;i++,j++)
for(int k=i;k<j;k++)
if(f[i][j]>f[i][k]+f[k+1][j])
f[i][j]=f[i][k]+f[k+1][j];
ans[i][j]=ans[i][k]+ans[k+1][j];
for(int k=i;k<j;k++)
int len=k-i+1;
if(l%len) continue;
if(check(a+i,l,len)&&f[i][j]>f[i][k]+2+num[l/len])
f[i][j]=f[i][k]+2+num[l/len];
ans[i][j]=to_string(l/len)+"("+ans[i][k]+")";
cout<<ans[1][n]<<'\\n';
return 0;
以上是关于P2400 秘密文件(区间dp)的主要内容,如果未能解决你的问题,请参考以下文章