zoukankan      html  css  js  c++  java
  • 严格递增类的dp Codeforces Round #371 (Div. 1) C dp

    http://codeforces.com/contest/713

    题目大意:给你一个长度为n的数组,每次有+1和-1操作,在该操作下把该数组变成严格递增所需要的最小修改值是多少

    思路:遇到这类题型,最普遍的方法就是把严格递增给变为递增就好了,所以我们对所有的a进行处理,a[i]-=i,然后再dp。

    我们对dp进行如下的定义:定义dp[i][j],dp[i][j]表示前i个数,1~i-1个数的val都<=b[j],目前第i个数修改成b[j](即第j大的数),所需要的最小花费dp[i][j] = min(dp[i][j - 1], dp[i - 1][j] + abs(a[i] - b[j]));

    因此我们就进行转移就好了

    //看看会不会爆int!数组会不会少了一维!
    //取物问题一定要小心先手胜利的条件
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define ALL(a) a.begin(), a.end()
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    #define haha; printf("haha
    ");
    /*
    我们定义,dp[i][j]表示前i个数,1~i-1个数的val都<=b[j],
    目前第i个数修改成b[j](即第j大的数),所需要的最小花费
    dp[i][j] = min(dp[i][j - 1], dp[i - 1][j] + abs(a[i] - b[j]));
    */
    const int maxn = 3000 + 5;
    LL dp[maxn][maxn];
    LL a[maxn], b[maxn];
    int n;
    
    int main(){
        scanf("%d", &n);
        for (int i = 1; i <= n; i++){
            scanf("%d", a + i);
            a[i] -= i;
            b[i] = a[i];
        }
        sort(b + 1, b + n + 1);
        for (int i = 1; i <= n; i++){
            dp[i][1] = dp[i - 1][1] + abs(a[i] - b[1]);
            for (int j = 2; j <= n; j++){
                dp[i][j] = min(dp[i][j - 1], dp[i - 1][j] + abs(a[i] - b[j]));
            }
        }
        printf("%I64d
    ", dp[n][n]);
        return 0;
    }
    View Code
  • 相关阅读:
    变量
    数据类型
    常量
    synchronized&volatile
    类,方法,成员变量和局部变量的可用修饰符
    类及其组成所使用的常见修饰符
    四种权限修饰符
    import
    finally
    final
  • 原文地址:https://www.cnblogs.com/heimao5027/p/5899266.html
Copyright © 2011-2022 走看看