POJ 3666 DP

链接:

http://poj.org/problem?id=3666

题意:

给你一个序列,求使它变成非递增或者非递减所需的最少花费

把a变成b的花费为|a-b|

题解:

事先知道了测试数据都是非递减的,所以就只写了非递减的,其实求非递增在反一下算一遍取最小值就行了

dp[i][j]表示第i个数以不超过b[j]结尾的最小值

代码:

 

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define mp make_pair
#define lson l,m,rt<<1  
#define rson m+1,r,rt<<1|1 
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
const ll MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int MAXN = 2010;
// head

int a[MAXN], b[MAXN];
int dp[MAXN][MAXN];

int main() {
    int n;
    cin >> n;
    rep(i, 1, n + 1) cin >> a[i], b[i] = a[i];
    sort(b + 1, b + n + 1);
    rep(i, 1, n + 1) dp[i][0] = INF;
    rep(i, 1, n + 1) rep(j, 1, n + 1)
        dp[i][j] = min(dp[i][j - 1], dp[i - 1][j] + abs(a[i] - b[j]));
    cout << dp[n][n] << endl;
    return 0;
}

 

posted @ 2017-04-18 17:35  Flowersea  阅读(239)  评论(0)    收藏  举报