poj 3666 Making the Grade (动态规划)

Making the Grade

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 4647   Accepted: 2202

Description

A straight dirt road connects two fields on FJ‘s farm, but it changes elevation more than FJ would like. His cows do not mind climbing up or down a single slope, but they are not fond of an alternating succession of hills and valleys. FJ would like to add
and remove dirt from the road so that it becomes one monotonic slope (either sloping up or down).

You are given N integers A1, ... , AN (1 ≤ N ≤ 2,000) describing the elevation (0 ≤ Ai ≤ 1,000,000,000) at each of N equally-spaced positions along the road, starting
at the first field and ending at the other. FJ would like to adjust these elevations to a new sequence B1, . ... , BN that is either nonincreasing or nondecreasing. Since it costs the same amount of money to add or remove
dirt at any position along the road, the total cost of modifying the road is

|AB1| + |AB2| + ... + |AN - BN |

Please compute the minimum cost of grading his road so it becomes a continuous slope. FJ happily informs you that signed 32-bit integers can certainly be used to compute the answer.

Input

* Line 1: A single integer: N

* Lines 2..N+1: Line i+1 contains a single integer elevation: Ai

Output

* Line 1: A single integer that is the minimum cost for FJ to grade his dirt road so it becomes nonincreasing or nondecreasing in elevation.

Sample Input

7
1
3
2
4
5
3
9

Sample Output

3

一个想法是:对于a[i],枚举任一高度作为最大高度,取前i-1个的合法最优解。

数据范围很大10^9,但n只有2000大小,可以离散化,用坐标代替高度。

a[i]存原始数组,b[j]存排序后递增的数组。

dp[i][j]=min(dp[i-1][0..j])+abs(a[i]-b[j]);  (把第i 个数高度改为b[j],此时的最小成本。)

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define ll __int64
#define mem(a,t) memset(a,t,sizeof(a))
#define N 2005
const int M=305;
const int inf=0x7fffffff;
int a[N],b[N];
int dp[N];
void solve(int n)
{
    int i,j,tmp;
    sort(b,b+n);
    for(i=0;i<n;i++)
    {
        dp[i]=abs(a[0]-b[i]);
    }
    for(i=1;i<n;i++)
    {
        tmp=dp[0];
        for(j=0;j<n;j++)
        {
            tmp=min(tmp,dp[j]);
            dp[j]=tmp+abs(a[i]-b[j]);
        }
    }
    int ans=inf;
    for(i=0;i<n;i++)
        ans=min(ans,dp[i]);
    printf("%d\n",ans);
}
int main()
{
    //freopen("in.txt","r",stdin);
    int i,n;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        b[i]=a[i];
    }
    solve(n);
    return 0;
}
时间: 2024-10-01 03:31:15

poj 3666 Making the Grade (动态规划)的相关文章

POJ 3666 Making the Grade [DP]

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

[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 Making the Grade (排序+dp)

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

POJ 3666 Making the Grade(数列变成非降序/非升序数组的最小代价,dp)

传送门: http://poj.org/problem?id=3666 Making the Grade Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9468   Accepted: 4406 Description A straight dirt road connects two fields on FJ's farm, but it changes elevation more than FJ would lik

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+离散化)

Description A straight dirt road connects two fields on FJ's farm, but it changes elevation more than FJ would like. His cows do not mind climbing up or down a single slope, but they are not fond of an alternating succession of hills and valleys. FJ

POJ 3666 Making the Grade

传送门:http://poj.org/problem?id=3666 解题思路: dp[i][j]:代表第i个数以j结尾所花的代价..那么dp[i][j]=fabs(a[i]-j)+min(dp[i-1][k])k<j; 实现代码: 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <cmath>

poj 3666 Making the Grade 【dp】

题目链接:http://poj.org/problem?id=3666 题意:使得一个序列变为递增或递减序列的最小代价.代价为题中给的公式. 解法:dp[i][j]表示前i个数,以num[j]为末尾的最小代价. 更新的时候枚举 j 转移状态: for (int i = 2; i <= n; i++) { int t = inf; for (int j = 1; j <= n; j++) { t = min(t,dp[i-1][j]); dp[i][j] = t + abs(a[i] - num

poj 3666 Making the Grade (线性结构上的DP )

题意: 给定n个数,问你将他们修改成非增或非减序列的最小花费.最小花费的定义是 假设原数组为 a[1] a[2] a[3] .... a[n] 修改后数组为 b[1] b[2] b[3] .... b[n] 那么最小花费为|a[1]-b[1]|+|a[2]-b[2]|+| a[3] - b[3] |+.....| a[n] - b[n] |. 思路: 线性结构上的动态规划 定义状态d[i][j] 表示 前i-1个数字已经是最小花费 现在把第i个数修改成b[j] 修改完成后前i个数总共最少需要的花