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;
    }
    
  • 相关阅读:
    (Tree) 101. Symmetric Tree
    (String). Word Pattern
    (Array)121. Best Time to Buy and Sell Stock
    (Array)169. Majority Element
    记录一次工作问题总结——关于游戏物体渲染顺序
    C++——STL(算法)
    观察者设计模式
    二分查找——校招题
    排序算法——归并排序
    排序算法——堆排序
  • 原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/14215260.html
Copyright © 2011-2022 走看看