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;

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=20000;
 8 const int M=210;
 9 int dp[M][N],n,m,q[N],head,tail,ans;
10 struct people{
11     int l,p,s;
12 }c[M];
13 bool cmp(people a,people b){
14     return a.s<b.s;
15 }
16 int read(){
17     int sum=0,f=1;char ch=getchar();
18     while(ch<‘0‘||ch>‘9‘){
19         if(ch==‘-‘)f=-1;
20         ch=getchar();
21     }
22     while(ch>=‘0‘&&ch<=‘9‘){
23         sum=sum*10+ch-‘0‘;
24         ch=getchar();
25     }
26     return sum;
27 }
28 int main(){
29     while(scanf("%d%d",&n,&m)!=EOF){
30         memset(dp,0,sizeof(dp));
31         for(int i=1;i<=m;i++){
32             c[i].l=read();c[i].p=read();c[i].s=read();
33         }
34         sort(c+1,c+1+m,cmp);
35         for(int i=1;i<=m;i++){
36             memset(q,0,sizeof(q));
37             head=1;tail=1;
38             for(int j=1;j<=n;j++){
39                 dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
40                 if(j>=c[i].s&&j<=c[i].s+c[i].l-1){
41                     while(head<=tail&&q[head]<j-c[i].l)head++;
42                     if(head>tail)continue;
43                     dp[i][j]=max(c[i].p*j+dp[i-1][q[head]]-c[i].p*q[head],dp[i][j]);
44                 }
45                 if(j<c[i].s){
46                     while(head<=tail&&dp[i-1][j]-c[i].p*j>=dp[i-1][q[tail]]-c[i].p*q[tail])tail--;
47                     q[++tail]=j;
48                 }
49             }
50         }
51         printf("%d\n",dp[m][n]);
52     }
53     return 0;
54 }

原文地址:https://www.cnblogs.com/Xu-daxia/p/9757131.html

时间: 2024-11-01 16:18:00

POJ 1821 Fence(单调队列优化DP)的相关文章

POJ 3926 Parade 单调队列优化DP

来源:http://poj.org/problem?id=3926 题意:行n <= 100, 列m <= 10000,类似于数字三角形,一个人要从底下往上走,每层中可以左右走,但选定方向不能回头(向左不能再向右),每经过一段获得该段的一个值,并走了该段的距离,在同一层走的距离不能超过k.问走到最顶头,获得的总值最大是多少. 分析:dp[i][j]表示走到第i行第j列,获得的值最大为多少.则dp[i][j] = max(dp[i+1][p] + sum(p to j)),sum(p to j)

POJ1821 Fence 单调队列优化DP

http://poj.org/problem?id=1821 题意:给长度为n的木板,k个工人,每个工人要么不粉刷,或者选择一个包含木板si,长度不超过li的连续的一段木板粉刷,每粉刷一块得到pi的报酬,问如何安排工人使得总报酬最大? 思路:可以按si给工人排序,这样我们就可以按照顺序依次安排工人.设f[i][j]表示到第i个工人,刷到前j块木板的最大报酬, 三种情况 工人不刷:f[i][j]=f[i-1][j] 木板空着:f[i][j]=f[i][j-1] 第i个工人刷k+1到j的木板,其中k

poj 1821 Fence(单调队列+dp)

Language: Default Fence Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4161   Accepted: 1288 Description A team of k (1 <= K <= 100) workers should paint a fence which contains N (1 <= N <= 16 000) planks numbered from 1 to N fro

POJ 3017 Cut the Sequence (单调队列优化DP)

POJ 3017 Cut the Sequence (单调队列优化DP) ACM 题目地址: POJ 3017 Cut the Sequence 题意: 将一个由N个数组成的序列划分成若干段,要求每段数字的和不超过M,求[每段的最大值]的和 的最小的划分方法,输出这个最小的和. 分析: 方程是:dp[i] = min(dp[j]+maxsum[j+1][i]) 但复杂度n*n太高,需要优化. 可以用单调队列+BST优化,其实只需要维护每一段的最大值. 看了这篇题解的:http://blog.cs

HDU 4122 Alice&#39;s mooncake shop 单调队列优化dp

Alice's mooncake shop Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4122 Description The Mid-Autumn Festival, also known as the Moon Festival or Zhongqiu Festival is a popular harvest festival celebrated by Ch

Tyvj1305最大子序和(单调队列优化dp)

描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7当m=2或m=3时,S=5+1=6 输入格式 第一行两个数n,m第二行有n个数,要求在n个数找到最大子序和 输出格式 一个数,数出他们的最大子序和 测试样例1 输入 6 4 1 -3 5 1 -2 3 输出 7 备注 数据范围:100%满足n,m<=300000 是不超过m,不是选m个!!!!! /* 单调队列优化dp 单调队列维护的是前

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-1][k]+k*Ap[i]的单调性即可 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int maxn = 2010; 6 int

1855: [Scoi2010]股票交易[单调队列优化DP]

1855: [Scoi2010]股票交易 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1083  Solved: 519[Submit][Status][Discuss] Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每个i,都有APi>=

BZOJ 1855 股票交易(单调队列优化DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1855 题意:最近lxhgww又迷上了投资股票, 通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每 个i,都有APi>=BPi),但是每天不能无限制地交易,于是股票交易所规定第i天的一次买入至多只能购买ASi股,一次卖出至多只能卖出BS