poj 1821 Fence





$ solution: $

这道题因为每一个粉刷的人都有一块“必刷的木板”,所以可以预见我们的最终方案里的粉刷匠一定是按其必刷的木板的顺序排列的。这就提示了我们可以用线性 $ DP $ ,只需要将粉刷匠按必刷的木板排序即可。

设 $ F[ $ i $ ][j] $ 表示前 $ i $ 个粉刷匠刷了前 $ j $ 快木板的最大收益(可以有木板不刷!)。我们可以根据题意列出转移方程:

  1. 首先这个粉刷匠一块木板也不刷
  2. 这块木板不刷
  3. 这个粉刷匠从第k块木板刷到第 $ j $ 块木板(这个有限制)

于是我们列出方程:

$ F[i][j]=max{F[i-1][j],\quad F[i][j-1],\quad ^{\quad max}_{j-L_i\leq k< S_i}{F[i-1][k]+P_i\times (j-k) } } $

然后我们发现前两个都好转移,但最后一个需要枚举耗费大量时间,而我们的数据范围就很不友好了。于是我们考虑如何优化:首先先将与k无关的项提取出来,这个可以直接放外面。

$ F[i][j]=^{\quad max}_{j-L_i\leq k< S_i}{F[i-1][k]-P_i\times k }+P_i\times j $

然后我们发现现在 $ max $ 函数里面的东西基本只和k有关, $ i $ 在循环枚举的外围可以相当于定值,于是我们可以用一个单调队列维护 $ F[i-1][k]-P_i\times k $ 这个东西,我们不能直接更新最大值,因为 $ j-L_i\leq k< S_i $ 会使我们之前的最大值失效,所以我们的单调队列需要满足双向删除,取队头(对头就是最优决策)。

总复杂度 $ O(N\times M) $



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int using namespace std; int n,m;
int b[16005];
int q[16005];
int f[105][16005]; struct su{
int l,s,v;
inline bool operator <(su x){
return s<x.s;
}
}a[105]; inline int ff(int i,int j){
return f[i-1][j]-a[i].v*j;
} inline int qr(){
register char ch; register bool sign=0; rg res=0;
while(!isdigit(ch=getchar())) if(ch=='-')sign=1;
while(isdigit(ch)) res=res*10+(ch^48),ch=getchar();
return sign?-res:res;
} int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
m=qr(); n=qr();
for(rg i=1;i<=n;++i){
a[i].l=qr(); a[i].v=qr(); a[i].s=qr();
} sort(a+1,a+n+1);
for(rg i=1;i<=n;++i){ rg l=1,r=0;
for(rg j=max(0,a[i].s-a[i].l);j<a[i].s;++j){
while(l<=r&&ff(i,j)>=ff(i,q[r]))--r;; q[++r]=j;
}
for(rg j=1;j<=m;++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],ff(i,q[l])+a[i].v*j);
}
}
}printf("%d\n",f[n][m]);
return 0;
}

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

  1. POJ 1821 Fence(单调队列优化DP)

    题解 以前做过很多单调队列优化DP的题. 这个题有一点不同是对于有的状态可以转移,有的状态不能转移. 然后一堆边界和注意点.导致写起来就很难受. 然后状态也比较难定义. dp[i][j]代表前i个人涂 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  10. hdu3401:单调队列优化dp

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

随机推荐

  1. 【Luogu】P1306斐波那契公约数(递推)

    题目链接 有个定理叫gcd(f(n),f(m))=f(gcd(n,m)) 所以递推就好了. #include<cstdio> #include<cstdlib> #includ ...

  2. [LA3620]Manhattan Wiring

    [LA3620]Manhattan Wiring 试题描述 输入 输出 输入示例 输出示例 数据规模及约定 见“输入” 题解 我们把“连线”的过程改为“铺地砖”的过程,总共有 11 种地砖,每种地砖上 ...

  3. HDU 1423 Greatest Common Increasing Subsequence ——动态规划

    好久以前的坑了. 最长公共上升子序列. 没什么好说的,自己太菜了 #include <map> #include <cmath> #include <queue> ...

  4. BZOJ 3168 [Heoi2013]钙铁锌硒维生素 ——矩阵乘法 矩阵求逆

    考虑向量ai能否换成向量bj 首先ai都是线性无关的,然后可以a线性表出bj c1*a1+c2*a2+...=bj 然后移项,得 c1/ci*a1+...-1/ci*bj+...=ai 所以当ci不为 ...

  5. 【2018.2.8-】网络流学习笔记(含ISAP!)

    网络流的基础内容就不详细发了,网上到处都是,可自学. 总版点这里 ps:以下有些链接是hihocoder的题目(题面有详细讲解),请确保先登录hihocoder,再点击进入相应题目网页. 最大流 基础 ...

  6. bzoj2324 [ZJOI2011]营救皮卡丘 费用流

    [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2653  Solved: 1101[Submit][Status][D ...

  7. poj 2891 模线性方程组求解

    Strange Way to Express Integers Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 8005   ...

  8. PXE+Kickstart 自动安装CentOS系统

    PXE (preboot execcute environment) 依赖服务 dhcp tftp file server (yum repository) 准备TFTP服务器  如何配置TFTP服务 ...

  9. Executors

    提供了工厂方法: Factory and utility methods for Executor, ExecutorService, ScheduledExecutorService, Thread ...

  10. P3367 并查集【模板】 洛谷

    https://www.luogu.org/problem/show?pid=3367#sub 题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入输出格式 输入格式: 第一行包含两个整 ...