


考试的时候写的方案不对,得了55pts
其实这道题目还是蛮明显的dp,然后需要记录一下状态,也就是方案
每次更新f[i]的时候,顺便对字符串进行一下排序修改(重载一下小于号即可)
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=55;
int t;
char s[maxn];
int has[30];
struct sting
{
int l;
char ss[55];
};
struct point
{
int ans;
sting c[55];
}f[55];
bool operator <(sting aa ,sting bb)
{
for(int i=1;i<=min(aa.l,bb.l);i++)
if(aa.ss[i]!=bb.ss[i])
return aa.ss[i]<bb.ss[i]?1:0;
return aa.l<bb.l?1:0;
}
bool operator <(point aa,point bb)
{
if(aa.ans!=bb.ans)
return aa.ans<bb.ans?1:0;
for(int i=1;i<=aa.ans;i++)
{
if(aa.c[i]<bb.c[i]) return 1;
if(bb.c[i]<aa.c[i]) return 0;
}
}
int main()
{
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
scanf("%d",&t);
while(t--)
{
scanf("%s",s+1);
int len=strlen(s+1);
for(int i=1;i<=len+1;i++) f[i].ans=len+1; // 赋值inf
for(int i=1;i<=len;i++)//计算f[i]
{
memset(has,0,sizeof(has));
for(int j=i-1;j>=0;j--)//枚举转移中间点j
{
if(has[s[j+1]-'a']) break;//判断有没有重复字母出现
has[s[j+1]-'a']=1;
point tmp; tmp=f[j];
tmp.ans++;
for(int k=j+1;k<=i;k++)//将j+1-i的串接上
{
tmp.c[tmp.ans].l++;
tmp.c[tmp.ans].ss[k-j]=s[k];
}
sort(tmp.c+1,tmp.c+tmp.ans+1);//按字典序排一下
if(tmp<f[i]) f[i]=tmp;
}
}
printf("%d\n",f[len].ans);
for(int i=1;i<=f[len].ans;i++)
{
for(int j=1;j<=f[len].c[i].l;j++)
printf("%c",f[len].c[i].ss[j]);
printf(" ");
}
printf("\n");
}
return 0;
}

本文介绍了一种使用动态规划(DP)算法解决特定字符串划分问题的方法。通过记录每个状态的最佳方案并进行适当的字符串排序修改,实现了高效求解。代码中详细展示了如何实现这一过程,包括状态定义、转移方程及优化技巧。
1450

被折叠的 条评论
为什么被折叠?



