解题报告: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
#include
#include
#include
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=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\n",dp[1][n]);
	return 0;
}

你可能感兴趣的:(解题报告:luogu P4170)