题解

以前做过很多单调队列优化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)的更多相关文章

  1. poj 1821 Fence 单调队列优化dp

    /* poj 1821 n*n*m 暴力*/ #include<iostream> #include<cstdio> #include<cstring> #incl ...

  2. $Poj1821\ Fence\ $单调队列优化$DP$

    Poj   Acwing Description 有N块木板等待被M个工匠粉刷,每块木板至多被刷一次.第i个工匠要么不粉刷,要么粉刷包含木块Si的,长度不超过Li的连续的一段木板,每粉刷一块可以得到P ...

  3. Dividing the Path POJ - 2373(单调队列优化dp)

    给出一个n长度的区间,然后有一些小区间只能被喷水一次,其他区间可以喷水多次,然后问你要把这个区间覆盖起来最小需要多少喷头,喷头的半径是[a, b]. 对于每个只能覆盖一次的区间,我们可以把他中间的部分 ...

  4. poj1821 Fence(单调队列优化dp)

    地址 一排N个木板,M个工匠站在不同位置$S_i$,每个人可以粉刷覆盖他位置的.最长长度为$L_i$木板段,每刷一个有$P_i$报酬.同一木板只刷一次.求最大报酬. 根据每个人的位置dp,设$f[i] ...

  5. 单调队列优化DP——习题收集

    前言 感觉可以用单调队列优化dp的模型还是挺活的,开个随笔记录一些遇到的比较有代表性的模型,断续更新.主要做一个收集整理总结工作. 记录 0x01 POJ - 1821 Fence,比较适合入门的题, ...

  6. 算法笔记--单调队列优化dp

    单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...

  7. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  8. 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 ...

  9. hdu3401:单调队列优化dp

    第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...

随机推荐

  1. RabbitMQ学习笔记(1)----RabbitMQ简介与安装

    ·1. 什么是RabbitMQ? RabbitMQ是流行的开源消息队列系统,用erlang语言开发.RabbitMQ是AMQP(高级消息队列协议)的标准实现. 而AMQP协议则是指:即Advanced ...

  2. ZBrush中Pinch捏挤笔刷介绍

    随着版本的升级ZBrush®中给我们提供了越来越多的笔刷,对于这款软件来说,笔刷的使用是第一要素,也会一直伴随我们创作.虽然Zbrush中有那么多的笔刷,但是很多朋友会根据自己的习惯来使用,这个并不是 ...

  3. 第十三章 Python并发编程

    并发编程之多进程 python中如果想要充分的利用多核CPU的资源,大部分情况需要使用多进程,python提供了multiprocessing multiprocessing模块用来开启子进程,并在子 ...

  4. 正式版的Linux Kernel 5.1来了,非LTS

    大神Linus Torvalds于今天发布了Linux Kernel 5.1内核正式版,在对现有功能进行改进的同时还带来了很多重要的改进.本次版本更新历时一个半月,不过值得注意的是它并非是长期支持版本 ...

  5. layui select change

    <select lay-filter="test"></select> layui.use([ 'form'], function() { var form ...

  6. 通过wget下载tomcat

    wget http://mirrors.cnnic.cn/apache/tomcat/tomcat-8/v8.0.42/bin/apache-tomcat-8.0.42.tar.gz 注意:下载之前确 ...

  7. OO第二单元总结——电梯调度问题

    一.设计策略. 在三次作业中,多线程程序的实现分以下几个步骤: 1. 主线程Main类的创建多个线程. 2. 共享对象的synchronized锁保证线程之间的互斥访问. 3. 采用notifyAll ...

  8. web前端-移动端响应式与自适应

    一. 在HTML的头部加入meta标签 在HTML的头部,也就是head标签中增加meta标签,告诉浏览器网页宽度等于设备屏幕宽度,且不进行缩放,代码如下: <meta name="v ...

  9. 【codeforces 234F】Fence

    [题目链接]:http://codeforces.com/problemset/problem/234/F [题意] 你有n块板要凃油漆; 然后每块板有高度h[i];(宽度都为1) 然后每块板只能凃同 ...

  10. hiho模拟面试题2 补提交卡 (贪心,枚举)

    题目: 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描写叙述 小Ho给自己定了一个雄伟的目标:连续100天每天坚持在hihoCoder上提交一个程序.100天过去了.小Ho查 ...