poj 3666 Making the Grade 动态规划+滚动数组

题意:给定一个序列,以最小代价将其变成单调不增或单调不减序列。

d[i][j] 代表前i个数最大为b[j]时的最小代价,d[i][j]=min(d[i-1][k])+abs(a[i]-b[j]),(0<k<=j),这里可以用滚动数组来存储min(d[i-1][k])。这里的滚动数组简直神来之笔,把一个二维数组压缩成一个变量,节省了大量时间空间。

题目bug,这里只求单调不减序列。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define INF 0x7fffffff
#define ll long long
#define N 2200
#define Abs(a) ((a)>0?(a):-(a))
using namespace std;

ll a[N],b[N];
long long int d[N][N];

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+n+1);
        memset(d,0,sizeof(d));
        for(int i=1;i<=n;i++)
        {
            ll mmin=d[i-1][1];
            for(int j=1;j<=n;j++)
            {
                mmin=min(mmin,d[i-1][j]);
                d[i][j]=mmin+Abs(a[i]-b[j]);
            }
        }
        ll ans=INF;
        for(int i=1;i<=n;i++)
            ans=min(ans,d[n][i]);
        cout<<ans<<endl;
    }
}


你可能感兴趣的:(dp,动态规划,poj,离散化,滚动数组)