POJ 1821 Fence(单调队列优化DP)
题解
以前做过很多单调队列优化DP的题。
这个题有一点不同是对于有的状态可以转移,有的状态不能转移。
然后一堆边界和注意点。导致写起来就很难受。
然后状态也比较难定义。
dp[i][j]代表前i个人涂完前j个位置的最大收益。
然后转移考虑
第i个人可以不刷。dp[i][j]=dp[i-1][j];
第j个木板可以不刷dp[i][j]=dp[i][j-1];
然后当c[i].s<=j<=s[i]+l[i]-1时
dp[i][j]=p[i]*j+max(dp[i-1][k]-p[i]*k)其中j-l[i]<=k<=s[i]-1;
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
const int M=;
int dp[M][N],n,m,q[N],head,tail,ans;
struct people{
int l,p,s;
}c[M];
bool cmp(people a,people b){
return a.s<b.s;
}
int read(){
int sum=,f=;char ch=getchar();
while(ch<''||ch>''){
if(ch=='-')f=-;
ch=getchar();
}
while(ch>=''&&ch<=''){
sum=sum*+ch-'';
ch=getchar();
}
return sum;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
memset(dp,,sizeof(dp));
for(int i=;i<=m;i++){
c[i].l=read();c[i].p=read();c[i].s=read();
}
sort(c+,c++m,cmp);
for(int i=;i<=m;i++){
memset(q,,sizeof(q));
head=;tail=;
for(int j=;j<=n;j++){
dp[i][j]=max(dp[i-][j],dp[i][j-]);
if(j>=c[i].s&&j<=c[i].s+c[i].l-){
while(head<=tail&&q[head]<j-c[i].l)head++;
if(head>tail)continue;
dp[i][j]=max(c[i].p*j+dp[i-][q[head]]-c[i].p*q[head],dp[i][j]);
}
if(j<c[i].s){
while(head<=tail&&dp[i-][j]-c[i].p*j>=dp[i-][q[tail]]-c[i].p*q[tail])tail--;
q[++tail]=j;
}
}
}
printf("%d\n",dp[m][n]);
}
return ;
}
POJ 1821 Fence(单调队列优化DP)的更多相关文章
- poj 1821 Fence 单调队列优化dp
/* poj 1821 n*n*m 暴力*/ #include<iostream> #include<cstdio> #include<cstring> #incl ...
- $Poj1821\ Fence\ $单调队列优化$DP$
Poj Acwing Description 有N块木板等待被M个工匠粉刷,每块木板至多被刷一次.第i个工匠要么不粉刷,要么粉刷包含木块Si的,长度不超过Li的连续的一段木板,每粉刷一块可以得到P ...
- Dividing the Path POJ - 2373(单调队列优化dp)
给出一个n长度的区间,然后有一些小区间只能被喷水一次,其他区间可以喷水多次,然后问你要把这个区间覆盖起来最小需要多少喷头,喷头的半径是[a, b]. 对于每个只能覆盖一次的区间,我们可以把他中间的部分 ...
- poj1821 Fence(单调队列优化dp)
地址 一排N个木板,M个工匠站在不同位置$S_i$,每个人可以粉刷覆盖他位置的.最长长度为$L_i$木板段,每刷一个有$P_i$报酬.同一木板只刷一次.求最大报酬. 根据每个人的位置dp,设$f[i] ...
- 单调队列优化DP——习题收集
前言 感觉可以用单调队列优化dp的模型还是挺活的,开个随笔记录一些遇到的比较有代表性的模型,断续更新.主要做一个收集整理总结工作. 记录 0x01 POJ - 1821 Fence,比较适合入门的题, ...
- 算法笔记--单调队列优化dp
单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...
- 单调队列优化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股 且一次 ...
随机推荐
- Django中ORM之查询表记录
查询相关API from django.db import models # Create your models here. class Book(models.Model): title = mo ...
- [USACO18FEB] Snow Boots G (离线+并查集)
题目大意:略 网上各种神仙做法,本蒟蒻只想了一个离线+并查集的做法 对所有靴子按最大能踩的深度从大到小排序,再把所有地砖按照积雪深度从大到小排序 一个小贪心思想,我们肯定是在 连续不能踩的地砖之前 的 ...
- Vue系列(三):组件及数据传递、路由、单文件组件、vue-cli脚手架
上一篇:Vue系列(二):发送Ajax.JSONP请求.Vue生命周期及实例属性和方法.自定义指令与过渡 一. 组件component 1. 什么是组件? 组件(Component)是 Vue.js ...
- C语言实现面向对象(转)
1.引言 面向对象编程(OOP)并不是一种特定的语言或者工具,它只是一种设计方法.设计思想. 它表现出来的三个最基本的特性就是封装.继承与多态. 很多面向对象的编程语言已经包含这三个特性了,例如 Sm ...
- jquery获得url的get参数
只是用了第一种方法,简单好用直接传入想要获取的参数名,即可返回参数值 function GetQueryString(name) { var reg = new RegExp("( ...
- 洛谷 1063 dp 区间dp
洛谷 1063 dp 区间dp 感觉做完这道提高组T1的题之后,受到了深深的碾压,,最近各种不在状态.. 初看这道题,不难发现它具有区间可并性,即(i, j)的最大值可以由(i, k) 与 (k+1, ...
- Mysql优化之优化工具profiling
程序员的成长之路 2016-11-23 22:42 Mysql优化之优化工具profiling 前言 mysql优化技术: mysql优化不是做一个操作就可以的优化,它包含很多的细节,需要一点一点的优 ...
- 洛谷 P1490 买蛋糕
P1490 买蛋糕 题目描述 野猫过生日,大家当然会送礼物了(咳咳,没送礼物的同志注意了哈!!),由于不知道送什么好,又考虑到实用性等其他问题,大家决定合伙给野猫买一个生日蛋糕.大家不知道最后要买的蛋 ...
- @crossorigin注解跨域
在@controller中类的头部有一个@CrossOrigin注解. @CrossOrigin是用来处理跨域请求的注解 先来说一下什么是跨域: (站在巨人的肩膀上) 跨域,指的是浏览器不能执行其他网 ...
- RandomAccessFile操作文件
package file; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; ...