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

【bzoj1260】[CQOI2007]涂色paint

2016-03-25 21:00 405 查看
题意:就是说一开始一个序列是空的,然后每次可以将连续的一段染成同一颜色,问多少次才能到目标状态。

一开始想的是二分,然后题解DP。。。

f[i][j]表示区间[i,j]需要染色多少次

首先初始状态是f[i][i]=1和f[i][i+1]=str[i]==str[i+1]

然后从短区间地推到长区间

对于f[i][j],若str[i]==str[j],则有f[i][j]=min{f[i+1][j],f[i][j-1],f[i+1][j-1]+1},否则f[i][j]=min{f[i][k]+f[k+1][j]∣i≤k<j}

复杂度:O(n^3)

#include<algorithm>

#include<iostream>

#include<cstdlib>

#include<cstring>

#include<cstdio>

#include<cmath>

using
namespace
std;


#define N 60


int
len;

int
f

;


char
str
;


int
main()

{

scanf
(
"%s"
,str+1);

len=
strlen
(str+1);

memset
(f,127/3,
sizeof
(f));

for
(
int
i=1;i<=len;i++)

f[i][i]=1;

for
(
int
l=1;l<=len;l++)

for
(
int
i=1;i<=len-l;i++)

{

int
j=i+l;

if
(str[i]==str[j])

if
(l==1)

f[i][j]=1;

else

{

f[i][j]=min(f[i+1][j],f[i][j-1]);

//
f[i][j]=min(f[i][j],f[i+1][j-1]+1);删了这句更快,0ms。。

}

else

for
(
int
k=i;k<j;k++)

f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);

}

printf
(
"%d\n"
,f[1][len]);

return
0;

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