Fence

Time Limit: 1000ms
Memory Limit: 30000KB

This problem will be judged on PKU. Original ID: 1821
64-bit integer IO format: %lld      Java class name: Main

 
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 from left to right. Each worker i (1 <= i <= K) should sit in front of the plank Si and he may paint only a compact interval (this means that the planks from the interval should be consecutive). This interval should contain the Si plank. Also a worker should not paint more than Li planks and for each painted plank he should receive Pi $ (1 <= Pi <= 10 000). A plank should be painted by no more than one worker. All the numbers Si should be distinct.

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

The input contains: 
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

The output contains a single integer, the total maximal income.

 

Sample Input

8 4
3 2 2
3 2 3
3 3 5
1 1 7

Sample Output

17

Hint

Explanation of the sample:

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

 
解题:单调队列优化dp
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = ;
struct Worker{
int L,S,P;
bool operator<(const Worker &rhs) const{
return S < rhs.S;
}
}a[maxn];
int n,m,L[maxn],R[maxn],dp[][maxn],q[maxn]; int main(){
while(~scanf("%d%d",&n,&m)){
for(int i = ; i <= m; ++i)
scanf("%d%d%d",&a[i].L,&a[i].P,&a[i].S);
sort(a + , a + m + );
for(int i = ; i <= m; ++i){
L[i] = max(,a[i].S - a[i].L);
R[i] = min(n,a[i].S + a[i].L - );
}
for(int i = ; i <= m; ++i){
for(int j = ; j <= R[i]; ++j)
dp[i][j] = dp[i-][j];
int hd = ,tl = ;
for(int j = L[i]; j < a[i].S; ++j){
while(hd < tl && dp[i-][j] - j*a[i].P >= dp[i-][q[tl-]] - q[tl-]*a[i].P) --tl;
q[tl++] = j;
}
for(int j = a[i].S; j <= R[i]; ++j){
while(hd < tl && j - q[hd] > a[i].L) ++hd;
dp[i][j] = max(dp[i-][j],dp[i][j-]);
dp[i][j] = max(dp[i][j],dp[i-][q[hd]] + (j - q[hd])*a[i].P);
}
for(int j = R[i] + ; j <= n; ++j)
dp[i][j] = max(dp[i-][j],dp[i][j-]);
}
int ret = ;
for(int i = ; i <= n; ++i)
ret = max(ret,dp[m][i]);
printf("%d\n",ret);
}
return ;
}

最新文章

  1. 好程序员带你了解一下HTTPS和SSL/TLS协议的背景与基础
  2. leetcode-【hard】273. Integer to English Words
  3. TreeMap源码分析
  4. 【BZOJ-1912】patrol巡逻 树的直径 + DFS(树形DP)
  5. 如何正确使用css中vertical-align
  6. acl拒绝访问流量
  7. JS 时分秒验证
  8. Top命令内存占用剖析
  9. Visual C++ 打印编程技术-打印基础知识
  10. Qt 内存泄漏测试
  11. spring自带定时器
  12. spring的配置和使用
  13. Windows Java安装
  14. 基于kettle的简单HTTP接口监控
  15. CentOS6下4网口绑定双IP
  16. python自学第9天,装饰器
  17. 在Java中调用C/C++本地库
  18. ubuntu系统升级和其他相关操作记录
  19. 结合 Redis 实现同步锁
  20. 隐藏和显示服务器端控件以及Html控件

热门文章

  1. bzoj1833
  2. /lib/dracut/hooks/shutdown/30-dm-shutdown.sh
  3. [Swift通天遁地]二、表格表单-(5)实现表格下拉和上拉刷新效果
  4. Akka源码分析-Actor创建(续)
  5. strupr函数
  6. python中的深拷贝和浅拷贝(面试题二)
  7. Flume特点
  8. 12 C#中的方法
  9. JQuery 记第N次被坑 - ajax请求字符集问题
  10. csf 课件转化为wmv正常格式