POJ3666Making the Grade[DP 离散化 LIS相关]

Making the Grade

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 6445   Accepted: 2994

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

Source

USACO 2008 February Gold


和那道CF#371(div.2)E一样,只是不严格单增单减各一遍

//
//  main.cpp
//  poj3666
//
//  Created by Candy on 9/22/16.
//  Copyright © 2016 Candy. All rights reserved.
//

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=2005,INF=1e9+5;
int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘; c=getchar();}
    return x*f;
}
int n,a[N],mp[N],k,ans=INF;
int f[N][N];
void dp(){
    sort(mp+1,mp+1+n);
    for(int i=1;i<=n;i++){
        int mn=INF;
        for(int j=1;j<=k;j++){
            mn=min(mn,f[i-1][j]);
            f[i][j]=mn+abs(a[i]-mp[j]);
        }
    }
    for(int j=1;j<=k;j++) ans=min(ans,f[n][j]);

    for(int i=1;i<=n;i++){
        int mn=INF;
        for(int j=k;j>=1;j--){
            mn=min(mn,f[i-1][j]);
            f[i][j]=mn+abs(a[i]-mp[j]);
        }
    }
    for(int j=1;j<=k;j++) ans=min(ans,f[n][j]);
}
int main(int argc, const char * argv[]) {
    n=read();
    for(int i=1;i<=n;i++){
        a[i]=mp[i]=read();
    }
    k=unique(mp+1,mp+1+n)-mp-1;
    dp();
    printf("%d",ans);
    return 0;
}
时间: 2024-10-25 20:09:00

POJ3666Making the Grade[DP 离散化 LIS相关]的相关文章

POJ 3666 Making the Grade (DP+离散化)

题目地址:POJ3666 dp[i][j]表示第i位时,值为j时的最小代价.因为j太大,由于要改变值的话,变到与之最近的值相同是最优的,所以可以离散化,这样,j对应了各个值得下标.复杂度O(n^2). 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h&

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 [DP]

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

【离散化+LIS】swjtuOJ 2091

[离散化+LIS]swjtuOJ 2091 [注:交大的看到这篇文章要学会自己写,不要为了比赛而比赛!~] 题目大意 给你两组n个数的序列,求他们最长公共序列(LCS),n<=10^5 对第一组序列数字编号,再对第二组序列构造他们编号对应的序列s,求解序列s的最长上升子序列即可(LIS) 说一下思路 这道题之前没做过,编号过程有人说是离散化,还不是很清楚,注意{a}序列中的数字可能在{b}序列不存在,要判断mp[a[i]]是否为空:LIS用O(NlogN)的算法,采用二分思想,这里顺便学习下了

动态规划(DP),类似LIS,FatMouse&#39;s Speed

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1108 解题报告: 1.首先按照weight从小到大排列,weight相同的按照speed从大到小排列; 2.Count[i]表示到第i个老鼠时,所求的最长“速度递减”子序列的长度: 3.path[i]=j是题目的关键,记录在Count[i]=Count[j]时,即最长“速度递减”子序列最后一个老鼠的前一只老鼠的位置 4.递归输出id void output(in

hoj_10001_朴素DP(LIS)

Longest Ordered Subsequence Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:32768KB Total submit users: 1937, Accepted users: 1621 Problem 10001 : No special judgement Problem description A numeric sequence of ai is ordered if a1 < a2 <

hoj_10027_优化DP(LIS)

Longest Ordered Subsequence Extention Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 778, Accepted users: 555 Problem 10027 : No special judgement Problem description A numeric sequence of ai is ordered if a1

Codeforces 13C Sequence --DP+离散化

题意:给出一个 n (1 <= n <= 5000)个数的序列 .每个操作可以把 n 个数中的某一个加1 或 减 1.问使这个序列变成非递减的操作数最少是多少 解法:定义dp[i][j]为将前i个数变为以j为结尾的非递减序列的最少操作次数. 则有: dp[i][j] = min(dp[i][j], min(dp[i][k]) + Cost(原来第i个位置上的数转换到j))  (1 <= k <= j) 即前i个数以j结尾的状态可以由前i-1个数以小于等于j的k结尾的状态转移过来,取

POJ 1185 炮兵阵地 状压DP+离散化优化

一开始能想到的状态就只有位压两行和当前行的行号,这样无论是空间和时间都是无法接受的. 但是因为炮兵的攻击范围比较大,而且又有地形限制,每一行的状态其实不多了,打表看了一下不超过80种,离散化一下就可以随意DP了. 据说题目也可以抽象成二分图最大匹配来搞?感觉复杂度有点高 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #i