POJ3666 线性dp_离散化_贪心
就DP而言这个题不算难,但是难就难在贪心,还有离散化的思想上
题目大意:n个土堆,问你最少移动多少单位的图,可以使得这n个土堆变成单调的
dp[i][j]表示前i个土堆高变为j时最优值
dp[i][j] = abs(j - a[i]) + min(dp[i-1][k])
到这里就有问题了,k遍历起来有多大,是吧,没法想‘?
所以搜了题解才知道:贪心的思想:如果选了一个c[i]得到最优值,那么必然可以通过转换,使得最终序列花费不变,并全部用原序列的数。
也有一个大佬的证明
假设存在a s <b i <=b i+1 <=⋯<=b j <a s+1 as<bi<=bi+1<=⋯<=bj<as+1
情况一:如果这些b都相等,那么把这些b都改成a s as 或者a s+1 as+1 肯定会有一种更优。
情况二:如果不全相等,那么肯定存在 b p b p+1 b p+2 ⋯b q bp bp+1 bp+2⋯bq ,他们的值相等,那么把他们移到左边的关键点或者右边的关键点,肯定有一种会更加优. 不断这样移动,最后就变成情况一了。
综上至少存在一种最优方案,最终的所有数都是原来的某个数。
因此可以离散化之后做dp,dp[i][j]表示把前i个数变成单调增(不严格)且第i个数变成原来第j大的数的最小代价。
这样关于k的遍历就好了但是我们真的还要去遍历k吗,只是一个最小值而已,只要记录一下不就好了
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#define inf (1 << 30)
using namespace std;
const int maxn = 2e3 + 2e2;
long long dp[maxn][maxn];
int a[maxn],b[maxn];
void init()
{
memset(dp,0,sizeof(dp));
}
//dp[i]表示前i个的最小花费
int main()
{
int n;
while(~scanf("%d",&n))
{
init();
for(int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
b[i] = a[i];
}
sort(b+1,b+1+n);
for(int i = 1;i <= n;i++)
{
long long m = dp[i-1][1];
for(int j = 1;j <= n;j++)
{
m = min(m,dp[i-1][j]);//m记录的是第i-1个数小于等于j时最小值
dp[i][j] = abs(a[i] - b[j]) + m;//这里层次记录为了i+1个数做铺垫
}
}
long long ans = inf;
for(int j = 1;j <= n;j++)
{
ans = min(ans,dp[n][j]);
}
printf("%lld\n",ans);
}
return 0;
}
POJ3666 线性dp_离散化_贪心的更多相关文章
- BZOJ_2151_种树_贪心+堆+链表
BZOJ_2151_种树_贪心+堆 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编 ...
- BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表
BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐 ...
- BZOJ_1691_[Usaco2007 Dec]挑剔的美食家_贪心
BZOJ_1691_[Usaco2007 Dec]挑剔的美食家_贪心 题意: 与很多奶牛一样,Farmer John那群养尊处优的奶牛们对食物越来越挑剔,随便拿堆草就能打发她们午饭的日子自然是一去不返 ...
- BZOJ_1697_[Usaco2007 Feb]Cow Sorting牛排序_贪心
BZOJ_1697_[Usaco2007 Feb]Cow Sorting牛排序_贪心 Description 农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行 ...
- BZOJ_1029_ [JSOI2007]建筑抢修_贪心+堆
BZOJ_1029_ [JSOI2007]建筑抢修_贪心+堆 Description 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是 ...
- BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP
BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀 ...
- [bzoj2097][Usaco2010 Dec]Exercise 奶牛健美操_贪心_树形dp_二分
Exercise bzoj-2097 Usaco-2010 Dec 题目大意:题目链接 注释:略. 想法:题目描述生怕你不知道这题在考二分. 关键是怎么验证?我们想到贪心的删边. 这样的策略是显然正确 ...
- poj3666/CF714E/hdu5256/BZOJ1367(???) Making the Grade[线性DP+离散化]
给个$n<=2000$长度数列,可以把每个数改为另一个数代价是两数之差的绝对值.求把它改为单调不增or不减序列最小代价. 话说这题其实是一个结论题..找到结论应该就很好做了呢. 手玩的时候就有感 ...
- Codeforces Round #532 (Div. 2) F 线性基(新坑) + 贪心 + 离线处理
https://codeforces.com/contest/1100/problem/F 题意 一个有n个数组c[],q次询问,每次询问一个区间的子集最大异或和 题解 单问区间子集最大异或和,线性基 ...
随机推荐
- HDU_2112(最短路)
经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强.这时候,XHD夫妇也退居了二线,并在风景秀美的诸暨市浬 ...
- Python之路(第六篇)Python全局变量与局部变量、函数多层嵌套、函数递归
一.局部变量与全局变量 1.在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量.全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序. 全局变量没有任何缩进,在任何位置都可 ...
- swift MD5 加密方法
引入OC类库 md5.h: #import <UIKit/UIKit.h> @interface Md5Controller : UIViewController @end md5.m: ...
- go语言字符串练习
package main import "fmt" import s"strings" var p = fmt.Println func main() { p( ...
- 解决maven update project 后项目jdk变成1.5的问题
一.问题描述 在Eclipse中新建了一个Maven工程, 然后更改JDK版本为1.7, 结果每次使用Maven > Update project的时候JDK版本都恢复成1.5. 二.原因分析 ...
- python输出格式对齐问题
采用.format打印输出时,可以定义输出字符串的输出宽度,在 ':' 后传入一个整数, 可以保证该域至少有这么多的宽度. 用于美化表格时很有用. >>> table = {'Goo ...
- Django高级篇一RESTful架构及API设计
一.什么是RESTful架构? 通过互联网通信,建立在分布式体系上"客户端/服务器模式”的互联网软件,具有高并发和高延时的特点. 简单的来说,就是用开发软件的模式开发网站.网站开发,完全可以 ...
- rbenv安装本地ruby安装包
cd .rbenv mkdir cache #把安装包拷进cache cd cache rbenv install 版本号
- ssh 常用命令
1.复制SSH密钥到目标主机,开启无密码SSH登录 ssh-copy-id user@host 如果还没有密钥,请使用ssh-keygen命令生成. 2.从某主机的80端口开启到本地主机2001端口的 ...
- 2018.12.15 codeforces 920F. SUM and REPLACE(线段树)
传送门 线段树入门题. 给你一个序列:支持区间修改成自己的约数个数,区间求和. 实际上跟区间开方一个道理. 2的约数个数为2,1的约数个数为1,因此只要区间的最大值小于3就不用修改否则就暴力修改. 因 ...