POJ 3666 Making the Grade

好难。。。
想了半天,用了类似于POJ 3186那样的DP写了一发,结果WA(其实写的时候也觉得过不了的。。。。)
结果看了别人的题解报告,发现真的有点难想到。。。。。。
首先要知道一个结论:
构造好之后最优解的数组中的每一个数字肯定在原数组中能找到
dp[i][j] 以第i个数字结尾,第i个数字用第j小的数字的最小花费
dp[i][j]=min(dp[i-1][k])+abs(a[i]-q[j]); (k<=j)
其中min(dp[i-1][k])是第三维循环,可以优化

另外,POJ数据弱,没开longlong都过了,而且仅算非递减的也可以AC。建议去FOJ提交。

//好难。。。
//想了半天,用了类似于POJ 3186那样的DP写了一发,结果WA(其实写的时候也觉得过不了的。。。。)
//结果看了别人的题解报告,发现真的有点难想到。。。。。。
//首先要知道一个结论:
//构造好之后最优解的数组中的每一个数字肯定在原数组中能找到
//dp[i][j] 以第i个数字结尾,第i个数字用第j小的数字的最小花费
//dp[i][j]=min(dp[i-1][k])+abs(a[i]-q[j]); (k<=j)
//其中min(dp[i-1][k])是第三维循环,可以优化
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

const int maxn=2000+10;
long long dp[maxn][maxn];
long long a[maxn],q[maxn];
long long MIN[maxn];
int n;

long long ABS(long long a)
{
    return max(a,-a);
}

bool cmp(const int&a,const int&b)
{
    return a>b;
}

int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%lld",&q[i]);
            a[i]=q[i];
        }

        //递增序列
        sort(q+1,q+n+1);
        memset(dp,-1,sizeof dp);
        memset(MIN,0,sizeof MIN);

        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++) dp[i][j]=MIN[j]+ABS(a[i]-q[j]);
            MIN[1]=dp[i][1];
            for(int j=2; j<=n; j++) MIN[j]=min(MIN[j-1],dp[i][j]);
        }
        long long ans1=dp[n][1];
        for(int i=2; i<=n; i++) ans1=min(ans1,dp[n][i]);

       //递减序列
        sort(q+1,q+n+1,cmp);
        memset(dp,-1,sizeof dp);
        memset(MIN,0,sizeof MIN);

        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++) dp[i][j]=MIN[j]+ABS(a[i]-q[j]);
            MIN[1]=dp[i][1];
            for(int j=2; j<=n; j++) MIN[j]=min(MIN[j-1],dp[i][j]);
        }
        long long ans2=dp[n][1];
        for(int i=2; i<=n; i++) ans2=min(ans2,dp[n][i]);

        printf("%lld
",min(ans1,ans2));

    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/5147274.html