zoukankan      html  css  js  c++  java
  • poj3666 Making the grade【线性dp】【离散化】

    Making the Grade
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions:10187   Accepted: 4724

    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

    题意:

    给定一个序列a,现在想要构造一个新序列是单调不增或单调不减的

    定义S为原序列和新序列对应位置数之差的绝对值之和

    要求S最小时的S

    思路:

    求单调不减和单调不增两个值 取最小【这道题有bug啊,就求了一个单调不减我就交了居然过了,不过反正同理】

    虐狗宝典上的方法一我没怎么看懂 n^3的算法还难理解 算了弃了

    引理:构造的新序列B中的数都在A中出现过 【数学归纳法可证】

    方法二就是一个二维的dp dp[i][j]表示以长度为i的子序列,且Bi == j时的S最小值

    dp[i][j] = a[i] - j + val, 其中val为min(dp[i - 1][k]), k < j

    然后先把a中出现的数离散化一下就行了

    今天学习到了一个新的离散化的方法

    先对数组sort, 然后使用unique函数

    unique函数将一个数组中相邻的相同的数删掉,只剩唯一一个

    unique(num, num + n) - num表示返回的数组的长度

      1 //#include <bits/stdc++.h>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<stdio.h>
      6 #include<cstring>
      7 #include<map>
      8 
      9 #define inf 0x3f3f3f3f
     10 using namespace std;
     11 typedef long long int LL;
     12 
     13 const double eps = 1e-8;
     14 
     15 int sgn(double x)
     16 {
     17     if(fabs(x) < eps) return 0;
     18     if(x < 0) return -1;
     19     else return 1;
     20 }
     21 struct point{
     22     double x, y;
     23     point(){}
     24     point(double _x, double _y)
     25     {
     26         x = _x;
     27         y = _y;
     28     }
     29     point operator -(const point &b)const
     30     {
     31         return point(x - b.x, y - b.y);
     32     }
     33     double operator ^(const point &b)const
     34     {
     35         return x * b.y - y * b.x;
     36     }
     37     double operator *(const point &b)const
     38     {
     39         return x * b.x + y * b.y;
     40     }
     41     void input()
     42     {
     43         scanf("%lf%lf", &x, &y);
     44     }
     45 };
     46 
     47 struct line{
     48     point s, e;
     49     line(){}
     50     line(point _s, point _e)
     51     {
     52         s = _s;
     53         e = _e;
     54     }
     55     pair<int, point>operator &(const line &b)const
     56     {
     57         point res = s;
     58         if(sgn((s - e) ^ (b.s - b.e)) == 0){
     59             if(sgn((s - b.e) ^ (b.s - b.e)) == 0){
     60                 return make_pair(0, res);
     61             }
     62             else return make_pair(1, res);
     63         }
     64         double t = ((s - b.s) ^ (b.s - b.e)) / ((s - e) ^ (b.s - b.e));
     65         res.x += (e.x - s.x) * t;
     66         res.y += (e.y - s.y) * t;
     67         return make_pair(2, res);
     68     }
     69 };
     70 
     71 bool inter(line l1, line l2)
     72 {
     73     return
     74         max(l1.s.x, l1.e.x) >= min(l2.s.x, l2.e.x) &&
     75         max(l2.s.x, l2.e.x) >= min(l1.s.x, l1.e.x) &&
     76         max(l1.s.y, l1.e.y) >= min(l2.s.y, l2.e.y) &&
     77         max(l2.s.y, l2.e.y) >= min(l1.s.y, l1.e.y) &&
     78         sgn((l2.s - l1.s) ^ (l1.e - l1.s)) * sgn((l2.e - l1.s) ^ (l1.e - l1.s)) <= 0 &&
     79         sgn((l1.s - l2.s) ^ (l2.e - l1.s)) * sgn((l1.e - l2.s) ^ (l2.e - l2.s)) <= 0;
     80 }
     81 
     82 double area(point a, point b, point c)
     83 {
     84     return fabs((1.0 / 2) * (a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)));
     85 }
     86 
     87 const int maxn = 2005;
     88 int n;
     89 int a[maxn], dp[maxn][maxn], num[maxn];
     90 map<int, int> mp;
     91 
     92 int main()
     93 {
     94     while(scanf("%d", &n) != EOF){
     95         int cnt = 0;
     96         for(int i = 1; i <= n; i++){
     97             scanf("%d", &a[i]);
     98             num[i] = a[i];
     99         }
    100         sort(num + 1, num + 1 + n);
    101         cnt = unique(num + 1, num + 1 + n) - num - 1;
    102         //cout<<cnt<<endl;
    103 
    104         memset(dp, inf, sizeof(dp));
    105         dp[0][0] = 0;
    106         for(int i = 1; i <= n; i++){
    107             int val = dp[i - 1][0];
    108             for(int j = 1; j <= cnt; j++){
    109                 if(dp[i - 1][j] < val){
    110                     val = dp[i - 1][j];
    111                 }
    112                 dp[i][j] =val + abs(a[i] - num[j]);
    113             }
    114         }
    115 
    116         int ans = inf;
    117         for(int i = 1; i <= cnt; i++){
    118             ans = min(ans, dp[n][i]);
    119         }
    120         printf("%d
    ", ans);
    121     }
    122     return 0;
    123 }
  • 相关阅读:
    操作系统学习五部曲
    由实模式进入保护模式
    extends && implements
    <mvc:annotation-driven>
    集合类关系
    Servlet8
    SprigMVC基础测试
    (转载)synchronized代码块
    jetty与tomcat
    输入输出流总结
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9740911.html
Copyright © 2011-2022 走看看