【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)
一开始想的是二分,然后题解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;
}
相关文章推荐
- leetcode——217——Contains Duplicate
- rails中如何在a标签中添加其他标签
- 【POJ 1691】 Painting A Board(dfs)
- [LeetCode]Palindrome Pairs
- PAT (Advanced Level) Practise 1090 Highest Price in Supply Chain (25)
- 主线程MainThread与渲染线程RenderThread
- http://www.cnblogs.com/hnrainll/archive/2011/12/29/2305582.html
- 【POJ 3411】 Paid Roads(搜索/DP)
- dcmtk进行movescu提示:Failed: IdentifierDoesNotMatchSOPClass
- 22. 使用 awk / grep / head / tail 命令进行文本 / 日志分析 (/home/D/acc.log)
- 配置rewrite
- The Responder Chain(响应链)
- leetcode-11 Container With Most Water
- EXPLAIN
- MacBook Air密码忘了,苹果电脑密码忘了怎么办
- Base Class Doesn't Contain Parameterless Constructor?
- PAT (Advanced Level) Practise 1086 Tree Traversals Again (25)
- Step by Step - Exchange 2013 Email Message Size Restriction Detail
- activity_main.xml解析
- ResourceManager High Availability