• 【题解】 bzoj1260: [CQOI2007]涂色paint (区间dp)


    bzoj1260,懒得复制,戳我戳我

    Solution:

    这种题目我不会做qwq,太菜了
    区间打牌(dp)

    • 用f[l][r]表示从l到r最少需要染几次色。
    • 状态转移方程:

    1.(f[l][r]=min(f[l][i],f[i+1][r]) (l<=i<r)) 这段染色等于俩段分别染色,很好看出来。
    2.(if(s[l]==s[r]) f[l][r]=min(min(f[l+1][r],f[l][r+1]),f[l+1][r-1]))

    • 分俩种一可以直接涂上俩端点,2是可以忽略掉左端点和右端点。
    • 第2点作用是很关键的,它会解决类似(ABACDA)之类的问题。忽略掉一段端点之后就可以继续找俩个端点进行染色。
    • 为什么是对的呢?因为最后无论如何都一个节点都需要涂一次,所有的同色的端点就也被涂了。

    转载的博客

    Code:

    //It is coded by Ning_Mew on 5.22
    #include<bits/stdc++.h>
    using namespace std;
     
    const int maxn=55;
     
    int n;
    string s;
    int dp[maxn][maxn];
     
    int main(){
      cin>>s;
      n=s.length();
      memset(dp,0x5f,sizeof(dp));
      for(int i=0;i<n;i++){dp[i][i]=1;}
      for(int len=2;len<=n;len++){
        for(int i=0;i<=n-len;i++){
          int ss=i,tt=i+len-1;
           
          if(s[ss]==s[tt])dp[ss][tt]=min(dp[ss][tt-1],dp[ss+1][tt]);
          if(s[ss]==s[ss+1])dp[ss][tt]=min(dp[ss][tt],dp[ss+1][tt]);
          if(s[tt]==s[tt-1])dp[ss][tt]=min(dp[ss][tt],dp[ss][tt-1]);
           
          for(int k=ss;k<tt;k++)
            dp[ss][tt]=min(dp[ss][tt],dp[ss][k]+dp[k+1][tt]);
        }
      }
      printf("%d
    ",dp[0][n-1]);
      return 0;
    }
    
  • 相关阅读:
    Linux Kernel USB 子系统(1)
    折腾 Gnome3
    2011年06月08日
    xelatex 果然好用
    倍受打击
    长到40岁学到的41件事
    autocompletemode + flyspellmode
    The Linux Staging Tree, what it is and is not.
    如何选择开源许可证?
    Use emacs &amp; Graphviz to plot data structure
  • 原文地址:https://www.cnblogs.com/Ning-Mew/p/9072844.html
Copyright © 2020-2023  润新知