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
  • 相关阅读:
    Spring Boot中的JSON技术
    Spring Boot中编写单元测试
    如何保证事务方法的幂等
    定时重试线程池
    多线程导致事务失效-记一次性能优化
    自己实现一个简单的数据库事务
    服务器错误码国际化
    spring自定义自动配置注解
    springboot中如何启动tomcat
    用grep来查询日志
  • 原文地址:https://www.cnblogs.com/heimao5027/p/5899266.html
Copyright © 2011-2022 走看看