题意:

给定长度为N的序列A,构造一个长度为N的序列B,满足:

1.B非严格单调,即B1 <= B2 <= ... <= BN 或 B1 >= B2 >= ... >= BN.

2.最小化 S = (累加)| Ai - Bi |,只需要求出这个最小值S.

1 <= N <= 2000,1 <= | Ai | <= 1e9

思路:

可以证明,我们能够只用A中的数字就可以构造出符合条件的B【虽然我不会证明,但是我觉得如果再遇到这种题,我应该也会这么猜的吧】。

既然可以用A中数字构造B,那么可以考虑先对A进行一个排序,本题单调增和单调减都需要求出,然后再比较最小值。【不过,写完之后发现只考虑单调增就可以通过本题,考虑单调减不可行】

这里只考虑单调增,因此用一个num数组将A复制下来,将num数组排升序,并且去重。由于n比较小,但是Ai很大,因此将Ai映射到数组中,进行离散化操作。

令dp[ i ][ j ]为B序列中最后一个数为num[ j ],并且前 i 个数字的cost最小,则

                   dp[ i ][ j ] = min(dp[ i-1 ][ x ]) + abs(a[ i ] - num[ j ])

由于更新dp[ i ][ j ]的时候,j始终不变,因此遍历过程中取一个最小值,进行依次更新,即可将On^3的复杂度降为On^2.

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define rep(i,a,b) for(int i = a;i <= b;i++)
using namespace std;int n;
int a[2500],num[2500];
int dp[2500][2500]; //dp[i][j]表示前i个数字花费最小,并且最后以num[j]结尾
//由于数字的范围很大,但是数字个数比较少,因此进行离散化,即把数字映射到区间上int main()
{while(~scanf("%d",&n)){rep(i,1,n){scanf("%d",&a[i]);num[i] = a[i];} sort(num+1,num+1+n);int m = unique(num+1,num+1+n)-num-1;memset(dp,0,sizeof dp);rep(i,1,n){//由于i不变,因此可以记录最小值int tmp = dp[i-1][1];rep(j,1,m){tmp = min(tmp,dp[i-1][j]);//dp[i][j] = min(dp[i-1][x])+abs(a[i]-num[j]); x <= j,保证升序dp[i][j] = tmp+abs(a[i]-num[j]);}}int ans = 0x3f3f3f3f;rep(i,1,m)ans = min(ans,dp[n][i]);printf("%d\n",ans);}return 0;
}

【POJ 3666】Making the Grade【线性DP】相关推荐

  1. poj 3666 Making the Grade zoj 3512 Financial Fraud 左偏树 or dp

    //poj 3666 //分析:只是在2005年集训队论文黄源河提到的题目上略微有一点点变化 1 #include"iostream" 2 #include"cstdio ...

  2. POJ 3666 Making the Grade 笔记

    N座山坡,山坡 i 高Ai.想修成只有上坡或只有下坡的形状.修后山坡 i 高Bi,修建费用是Ai与Bi差的绝对值之和.求最小费用.  

  3. 动态规划训练23 [Making the Grade POJ - 3666 ]

    Making the Grade POJ - 3666 这道题目有点意思. 我们定义dp[i][j]表示的含义是把包含前i个元素的子序列变成非递减的子序列,并且最后一个元素变成j所需要耗费的最小代价 ...

  4. POJ 3666 dp

    题意 传送门 POJ 3666 基本思路是对 N 个位置枚举所有可能高度,并 dp 求最大值.可能高度取 N 个位置的高度即可,排序以方便顺序 dp.对于升序的情况 dp[i][j]=max{dp[i ...

  5. poj 1088 滑雪(线性DP)

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 81553   Accepted: 30437 Description ...

  6. POJ - 1050 To the Max(最大连续子段和,线性dp)

    题目链接:点击查看 题目大意:给出一个n*n的矩阵,每个点都有一个权值,现在要从中选取一个子矩阵要求权值和最大,问这个最大权值和是多少 题目分析:因为是要求子矩阵的权值和最大的问题,我们可以直接维护一 ...

  7. 0x51.动态规划 - 线性DP(习题详解 × 10)

    目录 0x51.动态规划 - 线性DP 0x51.1 LIS问题 Problem A. 登山 (最长下降子序列) Problem B. 友好城市(思维) Problem C. 最大上升子序列和 0x5 ...

  8. UVA11584 划分成回文串 Partitioning by Palindromes(线性DP划分+DP判断回文串)

    整理的算法模板合集: ACM模板 依旧是线性DP 我们使用闫氏DP分析法 总体DP转移的时间复杂度为O(n2)O(n^2)O(n2). 但是这里牵扯到判断 i\tt ii 到 j\tt jj 是否为回 ...

  9. 洛谷P2401 不等数列(线性DP)

    本题使用的是线性DP.就是DP数组难以思考,这里我直接给出 dp[i][j]:表示 1 ~ i 这 i 个数 , 其中j 个 " < " 有几种方法 假设我们已经把 n - ...

  10. CodeForces - 1096D Easy Problem(线性dp)

    题目链接:点击查看 题目大意:给出一个字符串,每个字符都有一个权值,现在需要删除权值和最少的字符,满足字符串中不再含有子序列"hard" 题目分析:线性dp,但我不会,看着题解写的 ...

最新文章

  1. linux路由内核实现分析 四,linux路由内核实现分析(二)---FIB相关数据结构(4)
  2. 学点Webpack吧
  3. 在tomcat新建html页面,仅将HTML,CSS网页部署到Tomcat(示例代码)
  4. 深入源码,深度解析Java 线程池的实现原理
  5. 美橙互联域名与其他地方的区别
  6. Spring AOP自动创建代理 和 ProxyFactoryBean创建代理
  7. Async/Await FAQ
  8. matlab实验5函数文件,实验五M文件和MATLAB设计技术总结.doc
  9. 嵌入式语音识别系统是什么
  10. 考研数学一之高数上册学习计划
  11. 电脑上玩和平精英_和平精英奇幻之旅怎么玩-和平精英奇幻之旅玩法攻略
  12. 纽约出租车计费问题:一个简单的线性模型
  13. linux安装moodle最新版,于linux已安装moodle
  14. 京东自动签到领京豆软件_京东618来了,合法又简单的自动领京豆的技能要get一下吗?...
  15. 一款简单好用的动画/游戏制作软件|源码编辑器|编程猫南宁体验中心
  16. 怎样培养数据分析的能力
  17. WDF驱动中访问 PCI 设备配置空间
  18. TOM企邮、腾讯企邮、网易企邮、263企邮,四大企业邮箱实测:谁是最实用的企业邮箱产品?
  19. 1000行代码入门python-小白入门篇,Python到底是什么?
  20. ROG手机张舜翔:把游戏体验感当成游戏手机的重要支柱

热门文章

  1. 整理Oracle日期时间函数
  2. shell中的比较与测试
  3. Java之POI操作,封装ExcelUtil实现Excel导入导出
  4. php算数组内值的总和,怎样使用array_sum() 计算数组元素值总和
  5. java爬虫微信公众号信息_微信公众号爬虫项目(reptile)
  6. java输入学生名字输出_用java实现:输入学生个数,并输入每个学生的名字还有分数,结果输出分数最高和分数第二高的学生......
  7. python分布式爬虫_python-分布式爬虫
  8. 7-4 谁会留下?规则如下:所有的学生绕成一圈,顺序排号,从第一个学生开始报数,凡是报到固定数字(例如 5)的都退出,直到只剩下一位学生游戏才中止。 (10 分)
  9. linux 离线安装node.js,Linux上离线安装node.js、Newman、newman-reporter-html
  10. BNU29140 Taikotaiko(概率)