洛谷 P4170[CQOI2007]涂色 题解

原题地址

。差不多是个水题罢,难度个人认为是红
d p [ i ] [ j ] dp[i][j] 表示区间 [ i , j ] [i,j] 与答案匹配,考虑区间dp
i = j i=j ,则 d p [ i ] [ j ] = 1 dp[i][j]=1 ,显然
s [ i ] = s [ j ] s[i]=s[j] ,则 d p [ i ] [ j ] = m i n ( d p [ i + 1 ] [ j ] , d p [ i ] [ j 1 ] ) dp[i][j]=min(dp[i+1][j],dp[i][j-1]) ,相当于给 [ i , j 1 ] [ i + 1 , j ] [i,j-1]或[i+1,j] 刷一下,然后带着 i i j j 一起刷qwq
s [ i ] s [ j ] s[i]\not=s[j] ,则 d p [ i ] [ j ] = M i n k = i k < j d p [ i ] [ k ] + d p [ k + 1 ] [ j ] dp[i][j]=Min_{k=i}^{k<j}dp[i][k]+dp[k+1][j] ,分两个更小的区间涂,枚举断点。
假的蓝题。
C o d e \color{blue}Code :

# include <bits/stdc++.h>
using namespace std;
string s;
int n;
int dp[700][700];
void solve(void) 
{
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dp[i][j]=INT_MAX;
	for(int len=1;len<=n;len++) 
	{
		for(int i=1;i<=n;i++) 
		{
			int j=i+len-1;
			if(len==1) 
			{
				dp[i][j]=1;
			}
			else
			{
				if(s[i-1]==s[j-1]) 
				{
					dp[i][j]=min(dp[i+1][j],dp[i][j-1]) ;
				}
				else
				{
					for(int k=i;k<j;k++) 
					{
						dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]) ;
					}
				}
			}
		}
	}
	cout<<dp[1][n]<<endl; 
	return ;
}
int main(void)
{
	cin >> s;
	n=s.size() ;
	solve() ;
	return 0;
}
发布了29 篇原创文章 · 获赞 39 · 访问量 6684

猜你喜欢

转载自blog.csdn.net/woshidalaocxy/article/details/105166520