codeforces 13C. Sequence

来源:互联网 发布:nicelabel 数据库密码 编辑:程序博客网 时间:2024/05/22 05:28

摘自http://blog.csdn.net/crazy_ac/article/details/8799345

给你一串5000长度的数,要你将某些数变换一下,是的新的数列非递减

首先有个性质,就是变换后的数还是原来序列中的数,,,为为什么?假设每个数都是一棵某一高度的树,现在如果如果发现某个范围内的树的高度不满足单调性,那么就应该去改变某棵树的高度,要么增高它,要么砍掉一点,那增高或者砍掉到哪个值呢,肯定是附近的某棵树的高度!!画一画草图就ok了

所以可以构造出这样一个DP,dp[i][j]表示构造的序列中,前i个数,第i个数是小于等于a[j]的最小代价

/*********************************************** * Author: fisty * Created Time: 2015/2/2 19:11:50 * File Name   : A.cpp *********************************************** */#include <iostream>#include <cstring>#include <deque>#include <cmath>#include <queue>#include <stack>#include <list>#include <map>#include <set>#include <string>#include <vector>#include <cstdio>#include <bitset>#include <algorithm>using namespace std;#define Debug(x) cout << #x << " " << x <<endl#define Memset(x, a) memset(x, a, sizeof(x))const int INF = 0x3f3f3f3f;typedef long long LL;typedef pair<int, int> P;#define MAX_N 5010int arr[MAX_N];int b[MAX_N];int n;LL dp[MAX_N];int main() {    //freopen("in.txt", "r", stdin);    cin.tie(0);    ios::sync_with_stdio(false);    cin >> n;    for(int i = 1;i <= n; i++){        cin >> arr[i];        b[i] = arr[i];    }    sort(b+1, b + 1 + n);    Memset(dp, 0);    dp[0] = INF;    for(int i = 1;i <= n; i++){        for(int j = 1;j <=n;j++){            dp[j] += abs(arr[i] - b[j]);            dp[j] = min(dp[j-1], dp[j]);         }        cout << dp[i] << endl;    }    cout << dp[n] << endl;    return 0;}


0 0