0x59 单调队列优化DP
倍增DP太难啦心情好再回去做
poj1821 先让工匠按s排序,f[i][j]表示枚举到第i个工匠涂了j个木板(注意第j个木板不一定要涂)
那么f[i][j]可以直接继承f[i-1][j]和f[i][j-1]
此外 f[i][j]=max(j-l[i]+1<=k<=s[i]){f[i-1][k-1]+(j-k+1)*p}
按照单调队列运用的思想,维护f[i-1][k-1]-k*p的最大值
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node{int l,p,s;}a[];
bool cmp(node n1,node n2){return n1.s<n2.s;} int f[][];
int h,t,q[];
int main()
{
int m,n;
scanf("%d%d",&m,&n);
for(int i=;i<=n;i++)
scanf("%d%d%d",&a[i].l,&a[i].p,&a[i].s);
sort(a+,a+n+,cmp); memset(f,,sizeof(f));
for(int i=;i<=n;i++)
{
h=,t=;
for(int k=max(,a[i].s-a[i].l+);k<=a[i].s;k++)
{
while(h<=t&&f[i-][k-]-a[i].p*k>=f[i-][q[t]-]-a[i].p*q[t])t--;
q[++t]=k;
}
for(int j=;j<a[i].s;j++)f[i][j]=max(f[i-][j],f[i][j-]);
for(int j=a[i].s;j<=m;j++)
{
while(h<=t&&max(,j-a[i].l+)>q[h])h++;
f[i][j]=max(f[i-][j],f[i][j-]);
if(h<=t)f[i][j]=max(f[i][j],a[i].p*(j+)+f[i-][q[h]-]-a[i].p*q[h]);
}
}
printf("%d\n",f[n][m]);
return ;
}
poj1821
poj3017 神题(其实还好吧)
设f[i]表示1~i的最小值,f[i]=min(∑(k=j+1~i)a[k]<=m){f[j]+max(j+1~i)(a[k])}
然而,可以证明的是,可能成为最优决策的j,一定是j+1~i的最大值,或者是满足∑(k=j+1~i)a[k]<=m最小的j
那么就可以维护一个a[j]递减的单调队列,但是f[j]+max(j+1~i)(a[k])是不单调的,要用set把值记录
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
typedef long long LL; int a[],q[];
LL f[];
multiset<LL>s;
int main()
{
int n;LL m;
scanf("%d%lld",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]>m){printf("-1\n");return ;}
} int tp=;LL sum=;
int h=,t=;
for(int i=;i<=n;i++)
{
sum+=a[i];while(sum>m)sum-=a[tp++]; while(h<=t&&a[i]>=a[q[t]])
{
if(h<t)s.erase(f[q[t-]]+a[q[t]]);
t--;
}
q[++t]=i;
if(h<t)s.insert(f[q[t-]]+a[q[t]]);
while(h<=t&&tp>q[h])
{
if(h<t)s.erase(f[q[h]]+a[q[h+]]);
h++;
}
f[i]=f[tp-]+a[q[h]];
if(h<t)f[i]=min(f[i],*s.begin());
}
printf("%lld\n",f[n]);
return ;
}
poj3017
hdu2191 (纯粹是给单调队列维护多重背包找个例题)
把一个数拆成u+p*V的形式,f[u+p*V]=max(p-C<=k<=p-1){f[u+k*V]+(p-k)*W}
维护下f[u+k*V]-k*W
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int f[],q[];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int m,n,W,V,C;
scanf("%d%d",&m,&n);
memset(f,,sizeof(f));
for(int i=;i<=n;i++)
{
scanf("%d%d%d",&V,&W,&C);
for(int u=;u<V;u++)
{
int h=,t=; int li=(m-u)/V;
for(int k=max(,li-C);k<=li-;k++)
{
while(h<=t&&(f[u+q[t]*V]-q[t]*W)<=(f[u+k*V]-k*W))t--;
q[++t]=k;
}
for(int p=li;p>=;p--)
{
while(h<=t&&q[h]>p-)h++;
if(h<=t)f[u+p*V]=max(f[u+p*V],f[u+q[h]*V]+(p-q[h])*W);
if(p-C->=)
{
while(h<=t&&(f[u+q[t]*V]-q[t]*W)<=(f[u+(p-C-)*V]-(p-C-)*W))t--;
q[++t]=p-C-;
}
}
}
}
int ans=;
for(int i=;i<=m;i++)ans=max(ans,f[i]);
printf("%d\n",ans);
}
return ;
}
hdu2191
0x59 单调队列优化DP的更多相关文章
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
- bzoj1855: [Scoi2010]股票交易--单调队列优化DP
单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...
- hdu3401:单调队列优化dp
第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...
- Parade(单调队列优化dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others) ...
- BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP
BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...
- 【单调队列优化dp】 分组
[单调队列优化dp] 分组 >>>>题目 [题目] 给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择.你的任务是使得选出的数字的和最大 [输入格式] ...
- [小明打联盟][斜率/单调队列 优化dp][背包]
链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...
- 单调队列以及单调队列优化DP
单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...
- BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP
题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...
随机推荐
- informix 通过ADO或ODBC连接提取数据时出现中文乱码的解决方法
最近在做一个项目,是对INFORMIX数据库的数据进行大数据分析,INFORMIX数据库数据有上亿条,没有linux的Root权限和informix数据的生产权限,只能读取.客户要求结果显示在内网wi ...
- springboot + sharding-jdbc 学习
官网地址:http://shardingsphere.io/document/current/cn/overview/ sharding-jdbc事务:https://blog.csdn.net/ya ...
- 《Linux程序设计》笔记(二)shell程序设计
1. 进程树形显示 ps -e f 2. 重定向 > 覆盖文件 >> 附加至文件 1> 标准输出 2> 标准错误输出 0 代表一个程序的标准输入 3. 程序可以在当前目录 ...
- PAC学习理论:机器学习那些事
参考翻译,有大量删除和修改,如有异议,请拜访原文.一定要看英文原文!!!. 本文转载于:深度译文:机器学习那些事 英文[原题]A Few Useful Things to Know About Mac ...
- 虚拟机+linux+大杂烩
出于项目需要,需要用到linux系统.这玩意儿平时很少用,要说体验度还是windows更人性化一些. 1.虚拟机的安装,这个没说的,百度VMware直接下最新版安装就好. 2.接着是linux系统的安 ...
- 通用功能类:改变WinForm窗体显示颜色
一.显示窗体调用方法 protected override void OnLoad(EventArgs e) { MDIClientSupport.SetBevel ...
- 简单servlet调用dao层完整步骤
导入包lib(文件名称) 目录结构:web下:views.web-inf.index.jsp views下各种jsp文件和js(里面放封装好的jquery包) js下:jquery包(js文件后缀) ...
- BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会 树形DP + 带权重心
Description Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会.每个奶牛居住在 N(1<=N<=100,0 ...
- EF6 mysql配置
如何把一个ef项目 从sqlserver改为mysql 首先在引入了ef的层再引入这两个包,注意两个的版本一定要一样,一定要一样,一定要一样,不然就会报错 MySql.Data.Entity目前的最新 ...
- Day7 字符串和常用数据结构
字符串和常用数据结构 使用字符串 第二次世界大战促使了现代电子计算机的诞生,当初的想法很简单,就是用计算机来计算导弹的弹道,因此在计算机刚刚诞生的那个年代,计算机处理的信息主要是数值,而世界上的第一台 ...