cf 372 div2 E. Sonya and Problem Wihtout a Legend dp

题目地址: http://codeforces.com/contest/714/problem/E

题意:给一序列,可对这个序列的每个数做加一或减一的操作,问最小的操作数使这个序列变为严格递增序列

思路:看这个博客才明白的: http://blog.csdn.net/miracle_ma/article/details/52537208
首先如果题目要求的序列是非严格递增序列的话,则产生的新序列所含有的数一定可以都是原序列的数。
大致的证明思路:如果一个数要变小,那么这个数只要小到和它右边的数一样大就好了,再小得到的解不会是最优解;如果一个数要变大,那么这个数只要大到和它左边的数一样小就好了,再大得到的解不会是最优解。
试着把原问题转换为非严格递增序列的问题:只要使a[i]-=i就好了

转化为非严格递增后,如何解决,既然每个数都是原序列中的数,用dp[i][j]表示第i个数变为原序列第j大的数需要的成本,则有dp[i][j]=abs(b[i]-a[j])+min(dp[i-1][k]),b[i]指第i个数,a[j]指序列中第j大的数

#include
#include
#include
using namespace std;
typedef long long LL;
const int MAXN=3000+5;
int a[MAXN],b[MAXN];
LL maxn[MAXN],dp[MAXN][MAXN];
int main(){
    int n;
    while(~scanf("%d",&n)){
        for(int i=0;i


你可能感兴趣的:(好题,dp)