zoukankan      html  css  js  c++  java
  • 区间dp

     题意 :

      给你 n 个数字,相邻的数字如果相同,则代表他们是一个块的,每次操作可以将一个块的数字变成任意一种数字,求最小操作次数,将整个区间的所有数字变成相同的

    思路分析 :

      定义 dp[i][j][k]  k = 0 / 1 , dp[i][j][0] 表示将区间变成和左边数字一样的最小操作次数, dp[i][j][1] 表示将区间变成和右边数字一样的最小操作次数 , 然后就是正常的方程转移了

    代码示例 :

    int n;
    int a[5005];
    int dp[5005][5005][2];
    
    void solve(){
        for(int i = 1; i <= n; i++){
            for(int j = i; j <= n; j++){
                dp[i][j][0] = dp[i][j][1] = (i==j?0:inf);
            }
        }
        
        for(int len = 2; len <= n; len++){
            for(int i = 1; i <= n; i++){
                int j = i+len-1;
                if (j > n) break;
                
                if (i < n) {
                    dp[i][j][0] = min(dp[i][j][0], dp[i+1][j][0]+(a[i]!=a[i+1]));
                    dp[i][j][0] = min(dp[i][j][0], dp[i+1][j][1]+(a[i]!=a[j]));
                
                }
                if (j > 1) {
                    dp[i][j][1] = min(dp[i][j][1], dp[i][j-1][0]+(a[i]!=a[j]));
                    dp[i][j][1] = min(dp[i][j][1], dp[i][j-1][1]+(a[j-1]!=a[j]));
                }
            }
        }
        cout << min(dp[1][n][0], dp[1][n][1]) << endl;
    }
    
    int main() {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        cin >> n;
        for(int i = 1; i <= n; i++) cin >> a[i];
        solve();
        return 0;
    }
    
  • 相关阅读:
    CF 441E Valera and Number
    CodeForces 1111E. Tree
    CodeForces 1098F. Ж-function
    CodeForces 1098E. Fedya the Potter
    CodeForces 1098D. Eels
    CodeForces 1103E. Radix sum
    CodeForces 1103D. Professional layer
    CodeForces 1103C. Johnny Solving
    CodeForces 1107F. Vasya and Endless Credits
    Hackerrank: Week of Code 36
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/10362267.html
Copyright © 2011-2022 走看看