POJ3666-Making the Grade 【DP】

题意:给你一个序列A,你可以改变其中任意多个元素的值,使其变成单调序列B,花费的代价是| Ai  -  Bi | ,让你求最小代价。

思路:dp[i][j] 表示前i个数构成的序列中的最大值为j,所以可以有dp[i][j] = | ai - bj| + min(a[i - 1][k])  ( 0 <= k < j),很明显,我们可以用一个值来记录最小值,这样就省掉了一层循环,然后我们用离散化的思想对数组排序。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e3 + 10;
int a[maxn], b[maxn];
ll dp[maxn][maxn];
int main()
{
    int n;
    while(~scanf("%d", &n))
    {
        for(int i = 1; i <= n; ++i)
        {
            scanf("%d", &a[i]);
            b[i] = a[i];
        }
        sort(b + 1, b + n + 1);
        memset(dp, 0, sizeof(dp));
        for(ll i = 1; i <= n; ++i)
        {
            ll minn = dp[i - 1][1];
            for(int j = 1; j <= n; ++j)
            {
                minn = min(minn, dp[i - 1][j]);
                dp[i][j] += minn + abs(a[i] - b[j]);
            }
        }
        ll ans = dp[n][1];
        for(int i = 2; i <= n; ++i)
            ans = min(ans, dp[n][i]);
        cout << ans << endl;
    }
    return 0;
}

 

你可能感兴趣的:(动态规划)