您的位置:首页 > 大数据 > 人工智能

BZOJ 1260: [CQOI2007]涂色paint( 区间dp )

2015-07-17 23:44 573 查看


区间dp..

dp( l , r ) 表示让 [ l , r ] 这个区间都变成目标颜色的最少涂色次数.

考虑转移 :

l == r 则 dp( l , r ) = 1 ( 显然 )

s[ l ] == s[ l + 1 ] 则 dp( l , r ) = dp( l + 1 , r ) s[ r ] == s[ r - 1 ] 则 dp( l , r ) = dp( l , r - 1 ) 因为只要在涂色时多涂一格就行了, 显然相等 , 所以转移一下之后更好做

s[ l ] == s[ r ] 则 dp( l , r ) = min( dp( l + 1 , r ) , dp( l , r - 1 ) ) 相当于区间 [ l , r ] 被涂上了色 , 这样就可以转移到 dp( l , r - 1 ) 或者 dp( l + 1 , r )

其余的情况 : dp( l , r ) = min( dp( l , k ) + dp( k + 1 , r ) ) ( l <= k < r )

--------------------------------------------------------------------------

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream> #define rep(i ,n) for(int i=0; i < n; ++i)#define clr(x ,c) memset(x, c, sizeof(x)) using namespace std; const int maxl = 55; int d[maxl][maxl], n;char goal[maxl]; int dp(int l, int r) { int &t = d[l][r]; if(t != -1) return t; t = r - l + 1; if(goal[l] == goal[l + 1]) return t = dp(l + 1, r); if(goal[r] == goal[r - 1]) return t = dp(l, r - 1); if(goal[l] == goal[r]) return t = min(dp(l + 1, r), dp(l, r - 1)); for(int k = l; k < r; k++) t = min(t, dp(l, k) + dp(k + 1, r)); return t;} int main(){ freopen( "test.in" , "r" , stdin ); clr(d, -1); scanf("%s", goal); n = strlen(goal); rep(i, n) d[i][i] = 1; printf("%d\n", dp(0, n - 1)); return 0;}

--------------------------------------------------------------------------

1260: [CQOI2007]涂色paint

Time Limit: 30 Sec Memory Limit: 64 MB
Submit: 818 Solved: 496
[Submit][Status][Discuss]

Description

假设你有一条长度为5的木版,初始时没有涂过任何颜色。你希望把它的5个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为5的字符串表示这个目标:RGBGR。 每次你可以把一段连续的木版涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木版涂成RRRRR,第二次涂成RGGGR,第三次涂成RGBGR,达到目标。 用尽量少的涂色次数达到目标。

Input

输入仅一行,包含一个长度为n的字符串,即涂色目标。字符串中的每个字符都是一个大写字母,不同的字母代表不同颜色,相同的字母代表相同颜色。

Output

仅一行,包含一个数,即最少的涂色次数。

Sample Input

Sample Output

【样例输入1】
AAAAA

【样例输入1】
RGBGR

【样例输出1】
1

【样例输出1】
3

HINT

40%的数据满足:1<=n<=10
100%的数据满足:1<=n<=50

Source

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: