斜率优化dp(POJ1180 Uva1451)
学这个斜率优化dp却找到这个真心容易出错的题目,其中要从n倒过来到1的确实没有想到,另外斜率优化dp的算法一开始看网上各种大牛博客自以为懂了,最后才发现是错了。
不过觉得看那些博客中都是用文字来描述,还是应该用画图来表示更容易让人明白,不过时间不太够,且网上该题解法到处都是,就不累赘了。
代码才20几行真爽
更为详细的描述参见:
《浅谈数形结合思想在信息学竞赛中的应用》 周源
POJ 1180
稍微加深自己的印象
一般来说,斜率优化是从一些特殊数据的一些类似斜率的性质上找出其单调性。对于普通动态规划方程
例如 poj1180(不考虑反向来讨论)
F[i]=min(F[j]+(s+sumt[i]-sumt[j])*sumf[i])
因此我们可以考虑
在i之前
在k<j<i时,考虑使
F[j]+(s+sumt[i]-sumt[j])*sumf[i]<F[k]+(s+sumt[i]-sumf[k])*sumf[i]
化简后可得到
(F[j]-F[k])/(sumt[j]-sumt[k])<sumf[i]
可以类比斜率,如果满足这个条件,那么决策j就比决策k更好,因此我们令
ratio(k,j)=(F[j]-F[k])/(sumt[j]-sumt[k])
当满足ratio(k,j)<sumf[i]则有j好于k
而sumf[i]又是递增的,可以考虑单调队列。
那应该用一个怎样的单调队列来维护最优值呢?
什么值是不需要的?
当ratio(l,k)>ratio(k,j) (l<k<j)时
如果sumf[i]<ratio(k,j),则这些现在都不会是最优决策
如果ratio(k,j)<sumf[i]<ratio(l,k),则j优于k,l优于k
如果ratio(l,k)<sumf[i],则j最优
因此可以看出k是不需要的
因此可以将k节点删去,最后得到的单调队列则有保证ratio递增
关于单调队列具体操作:
1.将队列中头部满足ratio(head,head+1)<sumf[i]的所有删去,因为sumf是递增的,故此后永远满足head比head+1差,所以可以删去到ratio(head,head+1)>sumf[i],此时head即最优决策。
2.计算出新的ratio(tail,i)不断从尾部往前删除直到ratio(tail,i)>ratio(tail,tail-1).然后将i插入尾部即可
#include<cstdio>
#define Maxn 10005
int i,n,s,head,tail;
int sumt[Maxn],sumf[Maxn],ans[Maxn],p[Maxn];
inline double rat(int x,int y){
return((double)(ans[x]-ans[y])/(double)(sumt[x]-sumt[y]));
}
int main()
{
scanf("%d%d",&n,&s);
for(i=;i<=n;i++)
scanf("%d%d",&sumt[i],&sumf[i]);
for(i=n;i>=;i--){
sumt[i]+=sumt[i+];
sumf[i]+=sumf[i+];
while(head<tail&&rat(p[head],p[head+])<=sumf[i]) head++;
ans[i]=ans[p[head]]+sumf[i]*(s+sumt[i]-sumt[p[head]]);
while(head<tail&&rat(p[tail-],p[tail])>=rat(p[tail],i)) tail--;
p[++tail]=i;
}
printf("%d\n",ans[]);
return ;
}
Uva 14
本质上就是裸的斜率优化dp的转型
即求出一定条件下,图像上任意两点斜率的最大值。
#include <cstdio>
#include <cmath>
#define eps 1e-13
int ansl,ansr,n,l,d[],sum[];
double ans;
bool equ(double x,double y){
return(fabs(x-y)<eps);
}
inline double ratio(int a,int b){
return((sum[a]-sum[b])*1.0/(a-b));
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
sum[]=;
scanf("%d%d",&n,&l);
for(int i=; i<=n; i++){
scanf("%1d",&sum[i]);
sum[i]+=sum[i-];
}
ans=;
ansl=;ansr=l;//注意初始化,可能出现0000000
int g=,h=;
for(int i=l; i<=n; i++){
while(h>g&&ratio(d[h],i-l)<=ratio(d[h-],d[h]))
h--;
d[++h]=i-l;
while(g<h&&(ratio(d[g],i)<=ratio(d[g+],i)))
g++;
if(ratio(d[g],i)>ans&&!equ(ans,ratio(d[g],i)))
{
ans=ratio(d[g],i);
ansl=d[g]+;
ansr=i;
}
else if(equ(ans,ratio(d[g],i))&&i-d[g]<ansr-ansl+){
ansl=d[g]+;
ansr=i;
}
}
printf("%d %d\n",ansl,ansr);
}
return ;
}
斜率优化dp(POJ1180 Uva1451)的更多相关文章
- POJ1180 Batch Scheduling -斜率优化DP
题解 将费用提前计算可以得到状态转移方程: $F_i = \min(F_j + sumT_i * (sumC_i - sumC_j) + S \times (sumC_N - sumC_j)$ 把方程 ...
- 【学习笔记】动态规划—斜率优化DP(超详细)
[学习笔记]动态规划-斜率优化DP(超详细) [前言] 第一次写这么长的文章. 写完后感觉对斜优的理解又加深了一些. 斜优通常与决策单调性同时出现.可以说决策单调性是斜率优化的前提. 斜率优化 \(D ...
- bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)
题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- [BZOJ3156]防御准备(斜率优化DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP
- 【BZOJ-1096】仓库建设 斜率优化DP
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3719 Solved: 1633[Submit][Stat ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- BZOJ 3156: 防御准备 斜率优化DP
3156: 防御准备 Description Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小的战 ...
- HDU2829 Lawrence(斜率优化dp)
学了模板题之后上网搜下斜率优化dp的题目,然后就看到这道题,知道是斜率dp之后有思路就可以自己做不出来,要是不事先知道的话那就说不定了. 题意:给你n个数,一开始n个数相邻的数之间是被东西连着的,对于 ...
随机推荐
- location跳转和header跳转的区别
1:header("location:url") 跳转之前不能有任何输出,如果想在header之前有输出,则要修改php.ini文件.具体 output_handler =mb_o ...
- Opencv 的数据结构
opencv的基本数据结构 结构 成员 意义 CvPoint int x,y 图像中的点 CvPoint2D32f float x,y 二维空间中的点 CvPoint3D32f float x,y,z ...
- 关于Segmentation fault (core dumped)几个简单问题的整理
有的程序可以通过编译,但在运行时会出现Segment fault(段错误).这通常都是指针错误引起的.但这不像编译错误一样会提示到文件一行,而是没有任何信息.一种办法是用gdb的step, 一步一步寻 ...
- Python通过Manager方式实现多个无关联进程共享数据
Python官方文档 Python实现多进程间通信的方式有很多种,例如队列,管道等. 但是这些方式只适用于多个进程都是源于同一个父进程的情况. 如果多个进程不是源于同一个父进程,只能用共享内存,信号量 ...
- IOS game
App Store真是个金矿,即使是红海一片,黑马也依旧不少,前有愤怒的小鸟,现在出了个Flappy Bird,虽然是去年推出的,但最近爆红App Store和Google Play,越南河内的独立游 ...
- 基于SuperSocket实现的WebSocket(前端)
本文内容是搭配后端使用的,没看过WebSocket后端实现的童鞋们戳这里 咳咳,其实前端实现相对就容易很多了,因为我们有JavaScript WebSocket Api,它看上来大致是这样的: var ...
- WinForm 控件库
1:Telerik 介绍: Telerik 是保加利亚的一个软件公司,专注于微软.Net平台的表示层与内容管理控件.Telerik 提供高度稳定性和丰富性能的组件产品,并可应用在非常严格的环境中. 现 ...
- Contest2037 - CSU Monthly 2013 Oct (problem B :Scoop water)
http://acm.csu.edu.cn/OnlineJudge/problem.php?cid=2037&pid=1 [题解]:卡特兰数取模 h(n) = h(n-1)*(4*n-2)/( ...
- 防止IFRAME页被嵌套
防止IFRAME页被嵌套 //最大化窗口,防止窗口嵌套 if (parent.location != window.location){ parent.location = window.locati ...
- 想让安卓 APP 如丝般顺滑?
随着安卓手机市场占有率的节节攀升,随便在大街上找几个人估计 80% 用的都是安卓手机吧!用安卓手机的人这么多,不知道大家是否曾经感觉到过 APP 卡顿.死机?是否遇到应用程序无响应.闪退?本文就为大家 ...