【POJ 3666】Making the Grade【线性DP】
题意:
给定长度为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】相关推荐
- poj 3666 Making the Grade zoj 3512 Financial Fraud 左偏树 or dp
//poj 3666 //分析:只是在2005年集训队论文黄源河提到的题目上略微有一点点变化 1 #include"iostream" 2 #include"cstdio ...
- POJ 3666 Making the Grade 笔记
N座山坡,山坡 i 高Ai.想修成只有上坡或只有下坡的形状.修后山坡 i 高Bi,修建费用是Ai与Bi差的绝对值之和.求最小费用.
- 动态规划训练23 [Making the Grade POJ - 3666 ]
Making the Grade POJ - 3666 这道题目有点意思. 我们定义dp[i][j]表示的含义是把包含前i个元素的子序列变成非递减的子序列,并且最后一个元素变成j所需要耗费的最小代价 ...
- POJ 3666 dp
题意 传送门 POJ 3666 基本思路是对 N 个位置枚举所有可能高度,并 dp 求最大值.可能高度取 N 个位置的高度即可,排序以方便顺序 dp.对于升序的情况 dp[i][j]=max{dp[i ...
- poj 1088 滑雪(线性DP)
滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 81553 Accepted: 30437 Description ...
- POJ - 1050 To the Max(最大连续子段和,线性dp)
题目链接:点击查看 题目大意:给出一个n*n的矩阵,每个点都有一个权值,现在要从中选取一个子矩阵要求权值和最大,问这个最大权值和是多少 题目分析:因为是要求子矩阵的权值和最大的问题,我们可以直接维护一 ...
- 0x51.动态规划 - 线性DP(习题详解 × 10)
目录 0x51.动态规划 - 线性DP 0x51.1 LIS问题 Problem A. 登山 (最长下降子序列) Problem B. 友好城市(思维) Problem C. 最大上升子序列和 0x5 ...
- UVA11584 划分成回文串 Partitioning by Palindromes(线性DP划分+DP判断回文串)
整理的算法模板合集: ACM模板 依旧是线性DP 我们使用闫氏DP分析法 总体DP转移的时间复杂度为O(n2)O(n^2)O(n2). 但是这里牵扯到判断 i\tt ii 到 j\tt jj 是否为回 ...
- 洛谷P2401 不等数列(线性DP)
本题使用的是线性DP.就是DP数组难以思考,这里我直接给出 dp[i][j]:表示 1 ~ i 这 i 个数 , 其中j 个 " < " 有几种方法 假设我们已经把 n - ...
- CodeForces - 1096D Easy Problem(线性dp)
题目链接:点击查看 题目大意:给出一个字符串,每个字符都有一个权值,现在需要删除权值和最少的字符,满足字符串中不再含有子序列"hard" 题目分析:线性dp,但我不会,看着题解写的 ...
最新文章
- linux路由内核实现分析 四,linux路由内核实现分析(二)---FIB相关数据结构(4)
- 学点Webpack吧
- 在tomcat新建html页面,仅将HTML,CSS网页部署到Tomcat(示例代码)
- 深入源码,深度解析Java 线程池的实现原理
- 美橙互联域名与其他地方的区别
- Spring AOP自动创建代理 和 ProxyFactoryBean创建代理
- Async/Await FAQ
- matlab实验5函数文件,实验五M文件和MATLAB设计技术总结.doc
- 嵌入式语音识别系统是什么
- 考研数学一之高数上册学习计划
- 电脑上玩和平精英_和平精英奇幻之旅怎么玩-和平精英奇幻之旅玩法攻略
- 纽约出租车计费问题:一个简单的线性模型
- linux安装moodle最新版,于linux已安装moodle
- 京东自动签到领京豆软件_京东618来了,合法又简单的自动领京豆的技能要get一下吗?...
- 一款简单好用的动画/游戏制作软件|源码编辑器|编程猫南宁体验中心
- 怎样培养数据分析的能力
- WDF驱动中访问 PCI 设备配置空间
- TOM企邮、腾讯企邮、网易企邮、263企邮,四大企业邮箱实测:谁是最实用的企业邮箱产品?
- 1000行代码入门python-小白入门篇,Python到底是什么?
- ROG手机张舜翔:把游戏体验感当成游戏手机的重要支柱
热门文章
- 整理Oracle日期时间函数
- shell中的比较与测试
- Java之POI操作,封装ExcelUtil实现Excel导入导出
- php算数组内值的总和,怎样使用array_sum() 计算数组元素值总和
- java爬虫微信公众号信息_微信公众号爬虫项目(reptile)
- java输入学生名字输出_用java实现:输入学生个数,并输入每个学生的名字还有分数,结果输出分数最高和分数第二高的学生......
- python分布式爬虫_python-分布式爬虫
- 7-4 谁会留下?规则如下:所有的学生绕成一圈,顺序排号,从第一个学生开始报数,凡是报到固定数字(例如 5)的都退出,直到只剩下一位学生游戏才中止。 (10 分)
- linux 离线安装node.js,Linux上离线安装node.js、Newman、newman-reporter-html
- BNU29140 Taikotaiko(概率)