博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ1260: [CQOI2007]涂色paint
阅读量:4557 次
发布时间:2019-06-08

本文共 2594 字,大约阅读时间需要 8 分钟。

1260: [CQOI2007]涂色paint

Time Limit: 30 Sec  Memory Limit: 64 MB

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

from:

经典的区间dp题

对于一个给定的结束状态,我们考虑他是怎么转移的:

显然 只能是由一个子区间再往左涂一次或者再往右涂一次

那么对于任意一个大于二的序列都可以分成两个子序列,所以这就是一道区间dp了!(鼓掌!

很容易发现 如果最s[l]==s[l+1]||s[r]==s[r-1] 那么就不需要多余的次数来涂他了(因为一次可以把这两个都涂上)

但是下一个可能就没有那么好理解了(我居然浪费了两个多小时,我真是太弱啦!

如果s[l]==s[r]

那么可以证明 涂了l(或者r)的时候,这一次涂色一定同时涂上了r 不然不可能是最优解(因为即使r不是另一个区间所需要的颜色,答案也不会变的更差)

也就是说,转移方程为dp[l][r]=min(dp[l+1][r-1]+1,min(dp[l+1][r],dp[l][r-1]))  (s[l]==s[r])

因为取l和r,对另一个元素的贡献是等效的 所以只需要在他们中取min,并且这一次操作不会对答案产生改变

当然 另一种取法就是直接一笔从[l+1]画到[r-1] 这样答案++

以上属于特殊情况 对于其他的情况 只需要区间dp的经典递推式就可以了

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 using namespace std; 9 typedef long long ll;10 typedef long double ld;11 typedef pair
pr;12 const double pi=acos(-1);13 #define rep(i,a,n) for(int i=a;i<=n;i++)14 #define per(i,n,a) for(int i=n;i>=a;i--)15 #define Rep(i,u) for(int i=head[u];i;i=Next[i])16 #define clr(a) memset(a,0,sizeof(a))17 #define pb push_back18 #define mp make_pair19 #define fi first20 #define sc second21 #define pq priority_queue22 #define pqb priority_queue
, less
>23 #define pqs priority_queue
, greater
>24 #define vec vector25 ld eps=1e-9;26 ll pp=1000000007;27 ll mo(ll a,ll pp){ if(a>=0 && a
>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}29 void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }30 //void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; }31 int dx[5]={ 0,-1,1,0,0},dy[5]={ 0,0,0,-1,1};32 ll read(){ ll ans=0; char last=' ',ch=getchar();33 while(ch<'0' || ch>'9')last=ch,ch=getchar();34 while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();35 if(last=='-')ans=-ans; return ans;36 }37 const int N=100;38 int f[N][N];39 char ch[N];40 int main(){41 scanf("%s",ch+1); int n=strlen(ch+1);42 for (int p=1;p<=n;p++){43 for (int i=1;i<=n;i++){44 int j=i+p-1;45 if (j>n) continue;46 f[i][j]=j-i+1;47 if (i!=j && ch[i]==ch[j]) f[i][j]=min(f[i][j],f[i+1][j]),f[i][j]=min(f[i][j],f[i+1][j]);48 for (int k=i;k
View Code

 

 

转载于:https://www.cnblogs.com/SXia/p/7614779.html

你可能感兴趣的文章
【Windows 8 Store App】学习一:获取设备信息
查看>>
实现Windows程序的数据更新
查看>>
win10下VS2010中文输入法切换为英文卡死
查看>>
retinex相关代码汇总
查看>>
Cortex-M3 异常返回值EXC_RETURN
查看>>
Objective-C语言-内存管理
查看>>
迅雷API:实现文件下载
查看>>
Socket编程实践(2) Socket API 与 简单例程
查看>>
print 与标准输出
查看>>
pytest单元测试框架(day01)
查看>>
利用Azure Automation实现云端自动化运维(2)
查看>>
Linux学习说明
查看>>
【网络流24题】负载平衡问题(费用流)
查看>>
bzoj 3507 DP+哈希
查看>>
递归问题==优化 还有数据库sqlreader
查看>>
IOS第四天(2:字典转模型plist)
查看>>
什么是数据集
查看>>
Android开发数据库三层应用-DataSnap
查看>>
关于setTimeout运行机制
查看>>
2019 Multi-University Training Contest 4
查看>>