• 《算法竞赛进阶指南》0x51线性DP POJ3666分级


    题目链接:http://poj.org/problem?id=3666

    题目给出一个序列a,要求给出一个序列b使得两个数列每一项相减的绝对值之和最小,这里有一个重要的性质:存在一个满足条件的b,其中的数在a中都出现,可以通过数学归纳法去证明。

    然后就是dp的转移,前i个数设定好,并且第i个数是第j大的a中的数,这时的转移方程是dp[i][j]=min{dp[i-1][k]}+abs(a[i]-a'[j]),其中k属于[1,j]。

    通过前缀最大值的思想容易优化成O(n^2)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn = 2020;
    int a[maxn],b[maxn];
    int f[maxn][maxn];
    const int inf=0x7fffffff;
    int n;
    int dp(){
        for(int i=1;i<=n;i++)b[i]=a[i];
        sort(b+1,b+n+1);
        for(int i=1;i<=n;i++){
            int minv=inf;
            for(int j=1;j<=n;j++){
                minv=min(minv,f[i-1][j]);
                f[i][j]=minv+abs(a[i]-b[j]);
            }
        }
        int res=inf;
        for(int i=1;i<=n;i++)res=min(res,f[n][i]);
        return res;
    }
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        int res=dp();
        reverse(a+1,a+n+1);
        res=min(res,dp());
        cout<<res<<endl;
    }
    每一个不曾起舞的日子,都是对生命的辜负。
  • 相关阅读:
    Linux各目录的意义
    LinuxVIM编辑器用法
    Linux自动同步时间
    bash的基本特性
    shell-homeworkone
    shell
    笔记
    Python-1-Day
    Linux使用BIND提供域名解析服务
    Linuxautofs自动挂载服务
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13377919.html
Copyright © 2020-2023  润新知