bzoj1090(区间dp,字符串折叠问题)

这个问题比上一个简单一点,应该对比一下两题的相似与不同点,来找到解题的技巧

这题是用递推实现的,不用记忆化。

f【l】【r】表示,把l~r这个区间折叠的最短长度,

然后我们想,对于一个区间来说,我们有两种选择,一种是把这个区间它自己来折叠,另一种是两块已经折叠的区间接起来。

对于第二中情况,直接枚举断点(两道题中都用到的思路),再和答案取min,第一种则是,找出它所有的折叠方案,在折叠方案中取一个最优的


此题与上一题,思路的整理类比和分析:

首先这都是两道有关字符串压缩的题目,整体的思路都是对于一段区间,两类决策

1:由子问题更新的最优决策2:该区间本身进行压缩(进行处理)的最优决策

但是bzoj1068,M与R构成类似大括号进行压缩,但是一个M对应了不止一个R,这就是麻烦所在(不好转移),bzoj1090,就是括号对应括号,相对形象


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;

int f[105][105],g[105][105],n;
char s[105];

inline int tt(int x)
{
	if (x<10) return 1;
	if (x<100) return 2;
	return 3;
}

bool pan(int l,int r,int len)
{
	for (int i=1;i<=len;i++)
	{
		bool o=true;
		for (int j=l+i-1;j+len<=r;j+=len)
		if (s[j]!=s[j+len]) return false;
	}
	return true;
}

int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	for (int l=n;l>=1;l--)
	{
		f[l][l]=1;
		for (int r=l+1;r<=n;r++)
		{
			f[l][r]=r-l+1;
			for (int i=l;i<r;i++)
			f[l][r]=min(f[l][r],f[l][i]+f[i+1][r]);
			
			int len=r-l+1;
			for (int i=1;i<=len;i++)
			if (len%i==0&&pan(l,r,i))
				f[l][r]=min(f[l][r],f[l][l+i-1]+2+tt(len/i));
		}
	}
	
	printf("%d",f[1][n]);	
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值