POJ 3666 玄学dp

题意:给你一个序列A 构造一个序列B 使得B单调上升或单调下降 求序列B-序列A的绝对值的和的最小值

思考可知 序列B一定是由序列A中的数得来的 

所以用dp[i][j]记录把第i个数换成B[j]的最小花费

dp[i][j] = min(dp[i-1][1~j]+abs(A[i]-B[j]));

实际操作中第一层dp[i]没有什么意义 所以可以直接省略 很迷的一道题 真滴迷

AC代码:

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define inf 0x3f3f3f3f
int dp[2010];
int A[2010];
int B[2010];
int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> A[i];
        B[i] = A[i];
    }
    sort(B+1,B+1+n);
    for(int i = 1; i <= n; i++)
    {
        int z = inf;
        for(int j = 1; j <= n; j++)
        {
            z = min(dp[j],z);
            dp[j] = z + abs(B[j] - A[i]);
        }
    }
    int ans = inf;
    for(int i = 1; i <= n; i++)
    {
        ans = min(ans,dp[i]);
    }
    cout<

你可能感兴趣的:(算法竞赛进阶指南,dp)