HDU6212 区间dp 好题

拼搏现实的明天。 2022-05-12 02:08 288阅读 0赞

传送门

思路:要是对原串区间dp感觉无从下手,需要重要的一步就是转化,转化成连续的01数量串,比如10010=1211

这样的话每隔一个就是同一类的。

对于单个数字,需要的就是3-a[i],

对于一个区间,可以由三类转移

  1. 把区间分成 两份 例如 11 00 ans=2

2.中间消去两头相遇消去 例如11 00 1 ans=1

3.三块相遇消去 例如 1 00 1 00 11 ans=2

第三种情况这三块要满足中间必须是1,两边加起来和<=3, 因为这样消去 第一个00的时候,才不会出现将1消去的情况,

然后消去第二个00,三块相遇消去

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int dp[210][210], a[210];
  4. char s[210];
  5. int main(){
  6. int T, cas=0;
  7. scanf("%d", &T);
  8. while(T--){
  9. scanf("%s", s);
  10. int len=strlen(s);
  11. int m=1; a[m]=1;
  12. for(int i=1; i<len; i++){
  13. if(s[i]==s[i-1]) a[m]++;
  14. else a[++m]=1;
  15. }
  16. memset(dp, 0x3f, sizeof dp);
  17. for(int i=1; i<=m; i++)dp[i][i]=3-a[i], dp[i][i-1]=0;
  18. for(int t=1; t<m; t++){
  19. for(int i=1; i+t<=m; i++){
  20. int j=i+t;
  21. for(int k=i; k<j; k++){
  22. dp[i][j]=min(dp[i][j], dp[i][k]+dp[k+1][j]);
  23. if(t>=4 && a[k]==1 && ((k-i+1)&1) && ((j-k+1)&1) && a[i]+a[j]<=3)
  24. dp[i][j]=min(dp[i][j], dp[i+1][k-1]+dp[k+1][j-1]);
  25. }
  26. if((t+1)&1)
  27. dp[i][j]=min(dp[i][j], dp[i+1][j-1]+(a[i]+a[j]==2));
  28. }
  29. }
  30. printf("Case #%d: %d\n", ++cas, dp[1][m]);
  31. }
  32. return 0;
  33. }

发表评论

表情:
评论列表 (有 0 条评论,288人围观)

还没有评论,来说两句吧...

相关阅读

    相关 区间dp

    概念 区间dp就是在区间上进行动态规划,求解一段区间上的最优解。主要是通过合并小区间的 最优解进而得出整个大区间上最优解的dp算法。 借鉴大佬总结:[猛戳][Link

    相关 区间dp

    让我求解在一个区间上的最优解,那么我把这个区间分割成一个个小区间,求解每个小区间的最优解,再合并小区间得到大区间即可。所以在代码实现上,我可以枚举区间长度len为每次分割成的小