POJ1821 Fence
题意
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 6478 | Accepted: 2129 |
Description
Being the team's leader you want to determine for each worker the interval that he should paint, knowing that the total income should be maximal. The total income represents the sum of the workers personal income.
Write a program that determines the total maximal income obtained by the K workers.
Input
Input
N K
L1 P1 S1
L2 P2 S2
...
LK PK SK
Semnification
N -the number of the planks; K ? the number of the workers
Li -the maximal number of planks that can be painted by worker i
Pi -the sum received by worker i for a painted plank
Si -the plank in front of which sits the worker i
Output
Sample Input
8 4
3 2 2
3 2 3
3 3 5
1 1 7
Sample Output
17
Hint
the worker 1 paints the interval [1, 2];
the worker 2 paints the interval [3, 4];
the worker 3 paints the interval [5, 7];
the worker 4 does not paint any plank
Source
K个人对N块木板涂色,每个人初始站在一块木板前(不重复),每人最多只能涂包含所站木板的连续l个木板或一个木板也不涂。给出每人最多涂的木块数l,涂一快木板的工钱p,站的木板s。求这群人最多共获得多少工钱。
分析
参照mousehao001的题解。
dp[i][j]表示前i个人对前j块木板操作的最大收益。
核心状态转移方程:
dp[i][j]=max(dp[i][j-1],dp[i-1][k]+P[i].p*(j-k),dp[i-1][j])
max(0,P[i].s-P[i].l)<=k<min(P[i].s-1,j) k=0表示前i-1个人在玩泥巴。。
显然直接做就是枚举i,j,k。
观察dp[i-1][k]+P[i].p*(j-k)=(dp[i-1][k]-P[i].p*k)+P[i].p*j
在枚举k的时候,P[i].p*j的值已经确定不用考虑,只需要找出使(dp[i-1][k]-P[i].p*k)最大的k就行了,又观察到这个式子的值不与j相关,也就是说在枚举k之前我们就可以通过某种方法找出这个k,即:构造递减的 单调队列 维护k值。
时间复杂度\(O(MN)\)
代码
#include<iostream>
#include<algorithm>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;
co int N=16001,M=101;
struct rec{int L,P,S;}a[M];
bool operator<(co rec&a,co rec&b) {return a.S<b.S;}
int n,m,f[M][N],q[N];
int calc(int i,int k){
return f[i-1][k]-a[i].P*k;
}
int main(){
read(n),read(m);
for(int i=1;i<=m;++i) read(a[i].L),read(a[i].P),read(a[i].S);
sort(a+1,a+m+1);
for(int i=1;i<=m;++i){
int l=1,r=0;
for(int k=max(0,a[i].S-a[i].L);k<=a[i].S-1;++k){
while(l<=r&&calc(i,q[r])<=calc(i,k)) --r;
q[++r]=k;
}
for(int j=1;j<=n;++j){
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(j>=a[i].S){
while(l<=r&&q[l]<j-a[i].L) ++l;
if(l<=r) f[i][j]=max(f[i][j],calc(i,q[l])+a[i].P*j);
}
}
}
printf("%d\n",f[m][n]);
return 0;
}
POJ1821 Fence的更多相关文章
- [POJ1821]Fence(单调队列优化dp)
[poj1821]Fence 有 N 块木板从左至右排成一行,有 M 个工匠对这些木板进行粉刷,每块木板至多被粉刷一次.第 i 个工匠要么不粉刷,要么粉刷包含木板 Si 的,长度不超过Li 的连续一段 ...
- poj1821 Fence【队列优化线性DP】
Fence Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6122 Accepted: 1972 Description ...
- POJ1821 Fence 题解报告
传送门 1 题目描述 A team of $k (1 <= K <= 100) $workers should paint a fence which contains \(N (1 &l ...
- poj1821 Fence(单调队列优化dp)
地址 一排N个木板,M个工匠站在不同位置$S_i$,每个人可以粉刷覆盖他位置的.最长长度为$L_i$木板段,每刷一个有$P_i$报酬.同一木板只刷一次.求最大报酬. 根据每个人的位置dp,设$f[i] ...
- $Poj1821\ Fence\ $单调队列优化$DP$
Poj Acwing Description 有N块木板等待被M个工匠粉刷,每块木板至多被刷一次.第i个工匠要么不粉刷,要么粉刷包含木块Si的,长度不超过Li的连续的一段木板,每粉刷一块可以得到P ...
- poj1821 Fence(dp,单调队列优化)
题意: 由k(1 <= K <= 100)个工人组成的团队应油漆围墙,其中包含N(1 <= N <= 16 000)个从左到右从1到N编号的木板.每个工人i(1 <= i ...
- poj1821——Fence
题意: 一个栅栏一共有n(从1--n)个木板,我们找k个工人去粉刷它,li表示每个人有限制粉刷木板数量,pi表示粉刷一个木板得到的钱,si表示他开始在那个木板前面 如果一个工人要粉刷,那么他必须粉刷s ...
- 单调队列与DP
算是一个总结吧! 先来一个模板: TYVJ 1305 最大子序和 题目描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m ...
- Fence(poj1821)
Fence Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 4705 Accepted: 1489 Description ...
随机推荐
- CentOS磁盘用完的解决办法,以及Tomcat的server.xml里无引用,但是项目仍启动的问题
这是我2018年的第一篇博客...人真是懒了啊...最近在写微信小程序,觉得小程序做的也... 好了不吐槽了,言归正传 前言: 由于我之前不是买了个三年的香港服务器么 , 之前广州2的服务器我就没有续 ...
- U3D外包公司—北京动点(公司性质)承接U3D、Kinect、VR虚拟现实,增强现实,体感互动,大屏互动等各类外包
unity3d外包就找动点软件承接虚拟现实项目外包 承接U3D.Kinect.VR虚拟现实,增强现实,体感互动,大屏互动等各类外包 联系请加QQ:372900288 联系电话:13911652504 ...
- _pvp
comment 备注 zone 区域ID,.gps第二个参数 area 地域ID,.gps第三个参数 type 区域类型(保持原状.安全区.自由PVP.自由PVP - 禁止组队.自定义阵营(_fact ...
- Flex外包公司——案例汇总
Flex做的案例汇总: http://flex.org/showcase/ http://taggraph.com/everybody http://demoprod.informationbuild ...
- 学习:MQTT协议及原理
1 MQTT协议实现方式: 实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish).代理(Broker)(服务器).订阅者(Subscribe) ...
- 使用cookie记录页面跳转次数,然后从最后一级页面跳转回首页面
1.首先,给出cookie设置,获取,删除的操作函数. function setCookie(name,value) { var Days = 30; var ex ...
- QSplineSeries QChartView绘制曲线
参考资料: https://www.qtdebug.com/qtbook-paint-smooth-curve-qchart/ https://blog.csdn.net/liang19890820/ ...
- 使用blas做矩阵乘法
#define min(x,y) (((x) < (y)) ? (x) : (y)) #include <stdio.h> #include <stdlib.h> # ...
- erlang大法好
可惜haxe不能生成erlang.不过没关系,s6k输入法的实际执行方案,现在由typescript改用haxe.cdt3的ts地位不变. 以后这个博客大部分内容都是跟haxe/typescript相 ...
- css图形——椭圆
在css中,我们也使用border-radius属性来实现椭圆 语法 border-radius:x/y; 说明: x表示圆角的水平半径,y表示圆角的垂直半径. 例如:border-radius:30 ...