P4170 [CQOI2007] 涂色

17 篇文章 0 订阅
12 篇文章 0 订阅

      ~~~~~      P4170 [CQOI2007] 涂色       ~~~~~      总题单链接

思路

      ~~~~~      这道题的关键在于:对于两次涂色,要么不交,要么包含且端点不重。

      ~~~~~      证明:如果相交但不包含,缩短其中一个区间就可以变为不交的情况。

      ~~~~~       d p [ L ] [ R ] dp[L][R] dp[L][R] 表示将区间 [ L , R ] [L,R] [L,R] 涂色的最小次数,考虑两种情况。

      ~~~~~      第一种: s [ L ] = s [ R ] s[L]=s[R] s[L]=s[R] ,根据上面的性质,区间 [ L , R − 1 ] [L,R-1] [L,R1] 的第一次涂色一定包含了 L L L ,将这一次涂色的右端点改成 R R R 即可,所以 d p [ L ] [ R ] = d p [ L ] [ R − 1 ] dp[L][R]=dp[L][R-1] dp[L][R]=dp[L][R1]。同理,也可以 d p [ L ] [ R ] = d p [ L + 1 ] [ R ] dp[L][R]=dp[L+1][R] dp[L][R]=dp[L+1][R]

      ~~~~~      第二种: s [ L ] ≠ s [ R ] s[L]\neq s[R] s[L]=s[R] ,还是根据上面的性质,一定存在一个 i i i 使得没有区间跨过 i i i,枚举 i i i 即可。 d p [ L ] [ R ] = min ⁡ i < R i = L ( d p [ L ] [ i ] + d p [ i + 1 ] [ R ] ) dp[L][R]=\underset{i=L}{\overset{i<R}{\min}}(dp[L][i]+dp[i+1][R]) dp[L][R]=i=Lmini<R(dp[L][i]+dp[i+1][R])

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;

string s;
ll n,dp[55][55];

signed main(){
	ios::sync_with_stdio(false);
	
	cin>>s;s='.'+s;
	n=s.size()-1;
	
	memset(dp,0x3f,sizeof(dp));
	for(ll i=1;i<=n;i++)dp[i][i]=1;
	for(ll len=2;len<=n;len++)
		for(ll L=1;L+len-1<=n;L++){
			ll R=L+len-1;
			if(s[L]==s[R])dp[L][R]=dp[L][R-1];
			else{
				for(ll j=L;j<R;j++)
					dp[L][R]=min(dp[L][R],dp[L][j]+dp[j+1][R]);
			}
		}
		
	cout<<dp[1][n];
	
	return 0;
}
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值