【POJ】【1821】Fence

DP/单调队列优化



  题意:k个人粉刷总长为n的墙壁(或者说栅栏?),每个人有一个必刷点s[i](这个人也可以一点也不刷,如果刷就必须刷这个点),最大粉刷长度l[i](必须是连续粉刷一段),和粉刷一格的报酬p[i],每格不能重复粉刷,求最大报酬总和。

  唉……orz了一下proverbs,表示列dp方程是我的硬伤啊……

Tricks:

  转移!这个转移的边界没搞清……从$ s[i]-l[i] $到$ s[i]-1 $都是可行的,转移到的状态是$s[i]$到$s[i]+l[i]-1$

  排序!T_T很明显为了避免后效性是一定要先DP完$s$靠前的人的……sigh

 1 Source Code
 2 Problem: 1821        User: sdfzyhy
 3 Memory: 7036K        Time: 47MS
 4 Language: G++        Result: Accepted
 5
 6     Source Code
 7
 8     //POJ 1821
 9     #include<cmath>
10     #include<vector>
11     #include<cstdio>
12     #include<cstring>
13     #include<cstdlib>
14     #include<iostream>
15     #include<algorithm>
16     #define rep(i,n) for(int i=0;i<n;++i)
17     #define F(i,j,n) for(int i=j;i<=n;++i)
18     #define D(i,j,n) for(int i=j;i>=n;--i)
19     #define pb push_back
20     using namespace std;
21     int getint(){
22         int v=0,sign=1; char ch=getchar();
23         while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();}
24         while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();}
25         return v*=sign;
26     }
27     const int N=16010,M=110,INF=~0u>>2;
28     typedef long long LL;
29     /******************tamplate*********************/
30
31     int dp[M][N],n,k;
32     struct node{
33         int x,v;
34     }q[N];
35     struct ques{
36         int l,p,s;
37         bool operator <(const ques&b)const{
38             return s<b.s;
39         }
40     }a[M];
41     int main(){
42     #ifndef ONLINE_JUDGE
43         freopen("1821.in","r",stdin);
44         freopen("1821.out","w",stdout);
45     #endif
46         n=getint(); k=getint();
47         F(i,1,k){ a[i].l=getint(); a[i].p=getint(); a[i].s=getint();}
48         sort(a+1,a+k+1);
49         int l,p,s,st,ed;
50         F(i,1,k){
51             l=a[i].l; p=a[i].p; s=a[i].s;
52             st=ed=0;
53             F(j,0,n){
54                 dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
55                 if (j>=s-l && j<s){
56                     while(st<ed && q[ed-1].v<dp[i-1][j]-p*j) ed--;
57                     q[ed++]=(node){j,dp[i-1][j]-p*j};
58                 }
59                 if (j>=s && j<=s+l-1){
60                     while(st<ed && q[st].x<j-l) st++;
61                     dp[i][j]=max(dp[i][j],q[st].v+p*j);
62                 }
63             }
64         }
65         printf("%d\n",dp[k][n]);
66         return 0;
67     }

时间: 2024-10-19 10:27:26

【POJ】【1821】Fence的相关文章

最小树形图 【poj 3164 Command Network】

定义:在有向图上的最小生成树. 算法过程:和最小生成树一样,不过这个不是无向图的,但是也可以用类似的算法,最小树形图的第一个算法数朱刘算法,依据最小生成树数算法形成的. 我们知道,在最小生成树算法中,我们每次选长度最短的边,如果满足条件则加入最小生成树中,知道所有的点都在树中,最小树形图同样. 首先和最小生成树一样,首先必须保证图联通,否则不能形成最小树形图. 但是由于是有向的,而我们只要找所有点的入边中最小的入边的和就是这个图的最小树形图,但是最关键的地方在于可能形成环,我们要做的就是缩点,把

【POJ 1459 power network】

不可以理解的是,测评站上的0ms是怎么搞出来的. 这一题在建立超级源点和超级汇点后就变得温和可爱了.其实它本身就温和可爱.对比了能够找到的题解: (1)艾德蒙·卡普算法(2)迪尼克算法(3)改进版艾德蒙·卡普算法(MY METHOD) 不去管那个0ms的吧,那么(3)号算法最为美妙[它的别名是:ISAP],时间客观. 这个就算是一个ISAP的模板吧(除了输入的难看的几行外,其余均是标准的大米饼牌模板!) 1 #include<stdio.h> 2 #include<algorithm&g

【POJ 2823 Sliding Window】 单调队列

题目大意:给n个数,一个长度为k(k<n)的闭区间从0滑动到n,求滑动中区间的最大值序列和最小值序列. 最大值和最小值是类似的,在此以最大值为例分析. 数据结构要求:能保存最多k个元素,快速取得最大值,更新时删去“过期”元素和“不再有希望”的元素,安放新元素. 单调队列的基本概念百度百科讲得比较清楚了:http://baike.baidu.com/view/3771451.htm 我的大致思路是: 1. 每个元素存储为结构体,包含它的秩和值.维护最大长度为k的单调队列,保证所有元素的秩都在区间内

【POJ 3669 Meteor Shower】简单BFS

流星雨撞击地球(平面直角坐标第一象限),问到达安全地带的最少时间. 对于每颗流星雨i,在ti时刻撞击(xi,yi)点,同时导致(xi,yi)和上下左右相邻的点在ti以后的时刻(包括t)不能再经过(被封锁).安全地带为永远不会被封锁的点. 简单bfs,开始WA在把平面空间上限当成300*300,但根据题目,这只是有流星雨撞击的范围.实际可走的空间理论上没上限,但分析可得,离原点最近的安全地带一定在(302,302)范围内,所以应可把数组至少开为303*303. 后来WA在把G[0][0]==1的情

【 POJ - 1204 Word Puzzles】(Trie+爆搜)

Word Puzzles Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10782 Accepted: 4076 Special Judge Description Word puzzles are usually simple and very entertaining for all ages. They are so entertaining that Pizza-Hut company started using t

kuangbin专题四 最短路练习【从入门到熟练】

[POJ 2253 Frogger] 这道题求从u到v中所有通路的最大边最小 我直接二分做了,但实际上这种题是最短路算法的变种,意义在于告诉我们spfa这些算法不仅能维护出最短路,稍加修改后可以维护出很多其他东西. #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<string> #include

【POJ 1408】 Fishnet (叉积求面积)

[POJ 1408] Fishnet (叉积求面积) 一个1*1㎡的池塘 有2*n条线代表渔网 问这些网中围出来的最大面积 一个有效面积是相邻两行和相邻两列中间夹的四边形 Input为n 后面跟着四行 每行n个浮点数 每一行分别代表a,b,c,d 如图 并且保证a(i) > a(i-1) b(i) > b(i-1) c(i) > c(i-1) d(i) > d(i-1) n(n <= 30)*2+4(四个岸)条边 枚举点数就行 相邻的四个四个点枚举 找出围出的最大面积 找点用

【POJ 2513】Colored Sticks

[POJ 2513]Colored Sticks 并查集+字典树+欧拉通路 第一次做这么混的题..太混了-- 不过题不算难 字典树用来查字符串对应图中的点 每个单词做一个点(包括重复单词 题意就是每个边走且直走一次(欧拉通路 欧拉图的判定: 没有或者只有两个奇数度的点的图叫做欧拉图 有这些就可以解答此题了 另外需要注意题目范围是25W个木棍 所以最多可能有50W个点 卡了好多个RE 代码如下: #include <iostream> #include <cstdlib> #incl

2292: 【POJ Challenge 】永远挑战

2292: [POJ Challenge ]永远挑战 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 553  Solved: 230[Submit][Status][Discuss] Description lqp18_31和1tthinking经常出题来虐ftiasch.有一天, lqp18_31搞了一个有向图,每条边的长度都是1. 他想让ftiasch求出点1到点 N 的最短路."水题啊.", ftiasch这么说道. 所以1tth

poj 1808 Quadratic Residues 【平方剩余】【数论】

题目链接:http://poj.org/problem?id=1808 题目大意:给你T组数据,每组数据一个a一个n,判断 x^2  ≡  a ( mod  n ) 能否成立.成立则输出1否则输出-1. 一个简单的平方剩余,只用判断能否有解即可. #include<stdio.h> #define LL long long LL pow_mod(LL a, LL n, LL mod) { LL res = 1; while(n) { if (n & 1) res = res * a %