链接:
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; }