zoukankan      html  css  js  c++  java
  • 【dp每日一题】POJ 3666 Making the Grade

    大意:

    给出n个数,将这个数列修改为不增序列或者不减序列,需要的最小代价是多少(每次修改的代价为修改前后的差的绝对值)

    思路:

    贪心的想法是每次修改必然修改到原数列中存在的数,因为不这样修改必然会修改多了。

    然后先考虑修改到不减序列,那么可以先将a数组排序,得到b数组,然后(dp[i][j])代表将第i个数修改到(b[j])的代价最小值,那么这个最小值可以从(min(dp[i-1][1....j]))转移过来,但是这样复杂度很高,是(O(n^3))的,怎么优化呢,注意到每次更新j时也会更新(min(dp[i-1][1....j])),所以直接在更新(dp[i][j])的时候更新(min(dp[i][1....j]))即可,

    #include <math.h>
    #include <stdio.h>
    #include <string.h>
    
    #include <algorithm>
    #include <cstdio>
    #include <iostream>
    #include <queue>
    #include <stack>
    #include <vector>
    using namespace std;
    
    const int N = 2e3 + 5;
    typedef long long LL;
    
    int n, a[N], b[N], dp[N][N];
    int main() {
        cin >> n;
        for (int i = 0; i < n; i++) {
            cin >> a[i];
            b[i] = a[i];
        }
        sort(b, b + n);
        for (int i = 0; i < n; i++) dp[0][i] = min(dp[0][i], abs(a[0] - b[i]));
        for (int i = 1; i < n; i++) {
            int temp = dp[i - 1][0];
            for (int j = 0; j < n; j++) {
                temp = min(temp, dp[i - 1][j]);
                dp[i][j] = temp + abs(a[i] - b[j]);
            }
        }
        int res = dp[n - 1][0];
        for (int i = 0; i < n; i++) {
            res = min(res, dp[n - 1][i]);
        }
        cout << res << endl;
    }
    
  • 相关阅读:
    java多线程编程(一)
    java的本地文件操作
    Java基础总结(二)
    Gym 100851 Distance on Triangulation
    Gym 100851 题解
    Gym 101482 题解
    CodeForces Round 521 div3
    zoj 5823 Soldier Game 2018 青岛 I
    CodeForces round 520 div2
    CodeForces 1042 F Leaf Sets 贪心
  • 原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/14215260.html
Copyright © 2011-2022 走看看