POJ 3666(dp

题意:给出一个数列,求把它变成单调数列的最小成本,成本的定义是原始数列与结果数列每一项的差值的绝对值之和。

首先应该观察到,这个花费的计算与数列的顺序无关,如果调换结果数列的元素顺序,花费不变。

这样我们可以以数列的长度和最后一个数的大小作为递推下标,并且注意到结果数列中的数必然全部为原始数列中的数,所以可得如下dp。

import java.util.*;
import java.math.*;
import java.io.*;
public class Main {
    public static final int maxv=2000+40;
    public static void main(String[] args) throws Exception {
        Scanner in = new Scanner(new File("/home/develop/eclipse_file/ACMproject/src/in"));
        // Scanner in=new Scanner(System.in);
        int[][] dp=new int[maxv][maxv];
        int N;
        N=in.nextInt();
        int[] a=new int[N];
        int[] b=new int[N];
        for(int i=0;i<N;i++){
            a[i]=in.nextInt();
            b[i]=a[i];
        }
        Arrays.sort(b);
        for(int i=0;i<N;i++) dp[0][i]=Math.abs(a[0]-b[i]);
        for(int i=1;i<N;i++){
            int pre=dp[i-1][0];
            for(int j=0;j<N;j++){
                pre=Math.min(pre, dp[i-1][j]);
                dp[i][j]=Math.abs(a[i]-b[j])+pre;
            }
        }
        int ans=(int)1e9;
        for(int i=0;i<N;i++){
            ans=Math.min(ans, dp[N-1][i]);
        }
        System.out.println(ans);
        in.close();
    }
}

时间: 2024-10-09 22:20:53

POJ 3666(dp的相关文章

POJ 3666(Making the Grade)

题目链接:http://poj.org/problem?id=3666 题意:农夫约翰想修一条尽量平缓的路,路的每一段海拔是A_i,修理后是B_i,花费|A_i – B_i|,求最小花费.平缓的意思是海拔单调增或单调减(非严格) 思路: 这是一道动态规划的问题,突破口是:每个数最后必然是原序列中的数. 用dp[i][j]表示:前i个数构成的序列,这个序列最大值为j,dp[i][j]的值代表相应的cost. 状态转移方程:dp[i][j]=abs(j-w[i])+min(dp[i-1][k])  

POJ 1260-Pearls(DP)

Pearls Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7465   Accepted: 3695 Description In Pearlania everybody is fond of pearls. One company, called The Royal Pearl, produces a lot of jewelry with pearls in it. The Royal Pearl has its

POJ 1159-Palindrome(DP/LCS变形)

Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 53770   Accepted: 18570 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a

POJ 3661-Running(DP)

题目链接:点击打开链接 题意: 在一条直线上运动,每分钟可以运动距离a[i] ,每分钟可以选择运动或者休息,有一个疲劳系数,最初为0,每运动一分钟疲劳系数加1,(不能大于m) 同理,每休息一分钟,疲劳系数减1,(不能小于0)求n分钟后最大运动距离,要求n分钟时疲劳系数要为0. 两个状态,当前时间及当前疲劳系数.设 dp[i][j] =dp[i-1][j-1]+a[i] (j>0) else  dp[i][j] =max(dp[i][j],max(dp[i-k][0],dp[i-k][k]) )

POJ 1458(DP初步_B题)解题报告

题目链接:http://poj.org/problem?id=1458 -------------------------------------------------------- 题意:给你两个字符串, 要你求出两个字符串的最长公共子序列长度. 思路: 首先令dp[i][j]==x表示A串的前i个字符和B串的前j个字符的最长公共子序列长度为x. 初始化: dp全为0. 状态转移: IfA[i]==B[j] dp[i][j]= dp[i-1][j-1]+1 else dp[i][j]= ma

POJ 1297-Supermarket(DP)

题目大意:有M(1<=M<=100)个物品要买,在市场上有N(1<=N<=100000)个物品卖,要按列表顺序买齐这M个物品,并且这N个物品在街道上也是有顺序的,求最小花费是多少. 用d[i][j]表示当前买了列表的前i个物品并且走完了街道的前j个摊子的最小花费,那么分两种情况,如果第j个摊子卖的和在列表上第i个商品相同,那么可能从d[i-1][j-1]推来或d[i][j-1],即第j个摊子买或不买,若第j个摊子卖的不是列表上的第i个商品,那么就直接由d[i][j-1]推来. 程序

POJ 1321(DP初步_I题)解题报告

题目链接:http://poj.org/problem?id=1321 -------------------------------------------------------- 题意:给定棋盘区域,要求对于k个棋子存在多少种不同的摆放方案 思路:经典dfs,标记行列进行深搜,然后取消标记.循环得到摆放方案的种数 代码: #include<cstdio> #include<cstring> #include<algorithm> #include<iostr

hdu 1058 Humble Numbers || poj 1338(dp)

两题都是一样的题目 只是hdu 1058 多了个7 题意:求一个每个数因子仅含2 3 5 7 的 序列 问 第n个数是几 思路: ans[i]=min(min(ans[n2]*2,ans[n3]*3),min(ans[n5]*5,ans[n7]*7)); if(ans[i]==ans[n2]*2) n2++; if(ans[i]==ans[n3]*3) n3++; if(ans[i]==ans[n5]*5) n5++; if(ans[i]==ans[n7]*7) n7++; hdu 1058 #

POJ 1836-Alignment(DP/LIS变形)

Alignment Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 13465   Accepted: 4336 Description In the army, a platoon is composed by n soldiers. During the morning inspection, the soldiers are aligned in a straight line in front of the cap