Codeforces 607B Zuma(区间DP)

题目大概说,有n个颜色的宝石,可以消除是回文串的连续颜色序列,问最少要几下才能全部消除。

  • 自然想到dp[i][j]表示序列i...j全部消除的最少操作数
  • 有几种消除的方式都能通过枚举k(i<=k<j)从min(dp[i][k],dp[k+1][j])转移
  • 还有一种先消除中间的,剩余两部分组成回文串再消除,这种消除方式转移不会。。想到的时间复杂度太高。。
  • 看了tourist的代码,发现神的转移好简洁,这种方式就是从dp[i+1][j-1](c[i]=c[j])转移的
  • 应该可以这么理解,如果c[i]=c[j],而序列i+1...j-1消除到最后一步必定会剩下一个回文串!然后这个回文串就和c[i]和c[j]拼在一起,一起消除!感觉好强。。
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int c[555],d[555][555];
 6 int main(){
 7     int n;
 8     scanf("%d",&n);
 9     for(int i=0; i<n; ++i){
10         scanf("%d",c+i);
11     }
12     for(int i=0; i<n; ++i){
13         d[i][i]=1;
14         for(int j=i+1; j<n; ++j){
15             d[i][j]=11111111;
16         }
17     }
18     for(int len=2; len<=n; ++len){
19         for(int i=0; i+len-1<n; ++i){
20             int j=i+len-1;
21             for(int k=i; k<j; ++k){
22                 d[i][j]=min(d[i][j],d[i][k]+d[k+1][j]);
23             }
24             if(c[i]==c[j] && len==2) d[i][j]=1;
25             else if(c[i]==c[j]) d[i][j]=min(d[i][j],d[i+1][j-1]);
26         }
27     }
28     printf("%d",d[0][n-1]);
29     return 0;
30 }

 

转载于:https://www.cnblogs.com/WABoss/p/5677074.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值