解题报告:luogu P4170

Posted tlx-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解题报告:luogu P4170相关的知识,希望对你有一定的参考价值。

题目链接:P4170 [CQOI2007]涂色

区间 (dp) 好题。

我们假如已经有这个区间的最小步数:

[BRG ]

如果在区间右端添加一个 R 会怎么样呢?

考虑上一个涂到这个 R 未知的颜色是啥,显然是前面的这些之一或是他自己。

如果是他自己,那么:

[dp_{l,r}=dp_{l,r-1}+1 ]

如果上一个与他不相同的话,那么设位置为 (k)

[dp_{l,r}=dp_{l,k}+dp_{k+1,r-1}+1 ]

如果上一个颜色与他相同:

[dp_{l,r}=dp_{l,k}+dp_{k+1,r-1} ]

如果是在右面加元素同理。

(Code:)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;

#define inf 1000000000

char s[55];
int n,dp[55][55];

int main()
{
	scanf("%s",s);
	n=strlen(s);
	for(int i=n+1;i>=1;i--) s[i]=s[i-1];
	for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) dp[i][j]=inf;
	for(int i=0;i<=n;i++) dp[i][i]=1;
	for(int i=1;i<=n;i++) for(int j=0;j<i;j++) dp[i][j]=0;
	for(int i=2;i<=n;i++)
	{
		for(int l=1;l+i-1<=n;l++)
		{
			int r=l+i-1;
			dp[l][r]=dp[l][r-1]+1;
			for(int k=r-1;k>=l;k--)
			{
				if(s[k]==s[r]) dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r-1]);
				else dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r-1]+1);
			}
			dp[l][r]=min(dp[l][r],dp[l+1][r]+1);
			for(int k=l+1;k<=r;k++)
			{
				if(s[k]==s[l]) dp[l][r]=min(dp[l][r],dp[k][r]+dp[l+1][k-1]);
				else dp[l][r]=min(dp[l][r],dp[l+1][k-1]+dp[k][r]+1);
			}
		}
	}
	printf("%d
",dp[1][n]);
	return 0;
}

以上是关于解题报告:luogu P4170的主要内容,如果未能解决你的问题,请参考以下文章

luogu P4170ybtoj 区间DP课堂过关 例题2木板涂色 & [CQOI2007]涂色

解题报告:luogu P1160

解题报告:luogu P2299

解题报告:luogu P1892

解题报告:luogu P1445

解题报告:luogu P2572