POJ 3666 DP

给定一个序列,以最小代价将其变成单调不增或单调不减序列,这里的代价看题目公式

DP方程:dp[i][j]=abs(a[i]-b[j])+min(dp[i-1][k]);(k<=j)  前i个位置,结尾用b[j]的最小代价

详细题解:http://blog.csdn.net/wuyanyi/article/details/7255154

#include "stdio.h"
#include "string.h"
#include "algorithm"
using namespace std;

int Abs(int a)
{
    if (a<0) return -a;
    else return a;
}

int Min(int a,int b)
{
    if (a<b) return a;
    else return b;
}

int dp[2010][2010],a[2010],b[2010];

int main()
{
    int n,i,temp,j;
    while (scanf("%d",&n)!=EOF)
    {
        for (i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+1+n);

        for (i=1;i<=n;i++)
            dp[i][1]=Abs(a[1]-b[i]);

        for (i=2;i<=n;i++)
        {
            dp[i][1]=dp[i-1][1]+Abs(a[i]-b[1]);
            temp=dp[i-1][1];
            for (j=2;j<=n;j++)
            {
                temp=Min(temp,dp[i-1][j]);
                dp[i][j]=temp+Abs(a[i]-b[j]);
            }
        }
        temp=dp[n][1];
        for (i=2;i<=n;i++)
            temp=Min(temp,dp[n][i]);
        printf("%d\n",temp);
    }
    return 0;
}
时间: 2024-08-15 19:25:47

POJ 3666 DP的相关文章

POJ 3666 Making the Grade [DP]

题意: 给定一个序列,以最小代价将其变成单调不增或单调不减序列,这里的代价看题目公式. 思路: 很容易想到是DP. 1. 对前i个序列,构成的最优解其实就是与两个参数有关.一个是这个序列处理后的最大值mx,和这个序列处理的代价值cost. 显然最大值mx最小最好(这样第i+1个值可以不花代价直接接在其后面的可能性更大),cost最小也最好(题意要求),但是两者往往是鱼和熊掌. 用dp[i][j]表示:前i个数构成的序列,这个序列最大值为j,dp[i][j]的值代表相应的cost. 所以状态转移方

poj 3666 Making the Grade &amp; zoj 3512 Financial Fraud 左偏树 or dp

//poj 3666 //分析:只是在2005年集训队论文黄源河提到的题目上略微有一点点变化 1 #include"iostream" 2 #include"cstdio" 3 using namespace std; 4 const int maxn = 2100; 5 int v[maxn],l[maxn],r[maxn],d[maxn]; //节点信息 6 int N; 7 int tot,root[maxn],num_now[maxn],num_del[ma

Poj 3666 Making the Grade (排序+dp)

题目链接: Poj 3666 Making the Grade 题目描述: 给出一组数,每个数代表当前位置的地面高度,问把路径修成非递增或者非递减,需要花费的最小代价? 解题思路: 对于修好的路径的每个位置的高度肯定都是以前存在的高度,修好路后不会出现以前没有出现过得高度 dp[i][j]代表位置i的地面高度为第j个高度,然后我们可以把以前的路修好后变成非递减路径,或者把以前的路径首尾颠倒,然后修成非递减路径.状态转移方程为:dp[i][j] = min(dp[i-1][k]) + a[i] -

[2016-03-28][POJ][3666][]Making the Grade]

时间:2016-03-28 17:23:08 星期一 题目编号:[2016-03-28][POJ][3666][]Making the Grade] 分析:dp[i][j]表示把改到第i个数,且把a[i]改成b[i]需要的最少代价,已知b[j]递增,dp[i][j]由dp[i - 1][k]递推过来,如果改成非增,那么就要求 a[j] <= a[k],所以dp[i][j] = min(dp[i - 1][k] + d) k < j; #include <algorithm> #in

把一个序列转换成非严格递增序列的最小花费 POJ 3666

1 //把一个序列转换成非严格递增序列的最小花费 POJ 3666 2 //dp[i][j]:把第i个数转成第j小的数,最小花费 3 4 #include <iostream> 5 #include <cstdio> 6 #include <cstdlib> 7 #include <algorithm> 8 #include <vector> 9 #include <math.h> 10 // #include <memory.

HDU 1087 &amp;&amp; POJ 2533(DP,最长上升子序列).

~~~~ 两道题的意思差不多,HDU上是求最长上升子序列的和,而POJ上就的是其长度. 貌似还有用二分写的nlogn的算法,不过这俩题n^2就可以过嘛.. ~~~~ 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1087 http://poj.org/problem?id=2533 ~~~~ HDU1087: #include<cstdio> #include<cstring> #include<algorithm> #

POJ 3670 &amp;&amp; POJ 3671 (dp)

最长不下降子序列的应用嘛.两题都是一样的. POJ 3670:求给定序列按递增或递减排列时,所需改变的最小的数字的数目. POJ 3671:求给定序列按递增排列时,所需改变的最小的数字的数目. 思路就是求最长不下降子序列,然后剩下的就是需要改变的字母. 最长不下降子序列:(我之前有写过,不懂请戳)http://blog.csdn.net/darwin_/article/details/38360997 POJ 3670: #include<cstdio> #include<cstring

poj 3783 DP 2个鸡蛋扔100层楼的加强版

http://poj.org/problem?id=3783 估计23号之后的排位赛之后我就要退役了,这之前最后再做5天ACM 今天的排位很惨,上次排位也很惨......这道题原来算法课老师讲过,模模糊糊记得方程,但是边界处理有问题, dp[i][j]=min(1+max(dp[k-1][j-1],dp[i-k][j]))   k=1 to 楼数 dp[i][j]:i层楼扔,手里有j个ball 的次数 边界两个:1.dp[1][i]=1,第一层无论手里有几个鸡蛋都是1次,2.dp[i][1]=i

POJ 3034 DP

打地鼠游戏中,你有一个锤子,每一秒钟你可以拿着锤子移动d个单位的距离,必须是直线,掠过的鼠洞中露出的地鼠都会被锤打至,而事先知道从开始时各时间段内出现在老鼠的数量和位置,问题是从游戏开始至结束时,你最多能打到多少只地鼠,开始时锤子可以在任何位置. 题目有个陷阱, 只是说Moles出现的坐标为正,但没说hammer移动的位置要为正,可以为"any position" 所以锤子可以移出矩阵,再从矩阵外一点移进来 例: 20 5 4 1 0 1 0 1 1 0 5 2 1 6 2 0 0 0