首页 > 其他 > 详细

bzoj1260: [CQOI2007]涂色paint

时间:2016-07-13 01:23:26      阅读:252      评论:0      收藏:0      [点我收藏+]

区间dp。

用f[l][r]表示从l到r最少需要染几次色。

状态转移方程:

1.f[l][r]=min(f[l][i],f[i+1][r]) (l<=i<r) 这段染色等于俩段分别染色,很好看出来。

2.if(s[l]==s[r]) f[l][r]=min(min(f[l+1][r],f[l][r+1]),f[l+1][r-1])。

分俩种一可以直接涂上俩端点,2是可以忽略掉左端点和右端点。

第2点作用是很关键的,它会解决类似ABACDA之类的问题。忽略掉一段端点之后就可以继续找俩个端点进行染色。

为什么是对的呢?因为最后无论如何都一个节点都需要涂一次,所有的同色的端点就也被涂了。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 200 + 10;

int n;
int f[maxn][maxn];
char s[maxn];

int dp(int l,int r) {
    if(l>r) return 0;
    if(l==r) return 1;
    if(f[l][r]) return f[l][r];
    int &res=f[l][r];
    res=r-l+1;
    for(int i=l;i<r;i++) res=min(res,dp(l,i)+dp(i+1,r));
    
    if(s[l]==s[r]) res=min(res,min(min(dp(l,r-1),dp(l+1,r)),dp(l+1,r-1)+1));
    return res;
}

int main() {
    scanf("%s",s+1);
    printf("%d\n",dp(1,strlen(s+1)));
    return 0;
}

bzoj1260: [CQOI2007]涂色paint

原文:http://www.cnblogs.com/invoid/p/5665261.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!