【2020模拟赛day7】 A. 字符排序

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

 

考试的时候写的方案不对,得了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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值