单调队列1007 Codeforces Round #219 (Div. 1) 372C. Watching Fireworks is Fun
来源:互联网 发布:网络统考时间 编辑:程序博客网 时间:2024/05/23 10:40
题意:
在一条街上有n个点.之后会有m个烟花点燃
每个烟花有三种属性
ai bi ti
ai代表烟花点燃的位置
ti代表烟花点燃的时间
假设当前人在位置x
那么就会得到一个值bi-|ai-x|
在第0秒的时候,位置是随意的
每秒可以移动<=d的位置
问点燃完m个烟花后得到值得和的最大值
思路:
我们需要求sigma(bi-|ai-x|)->
sigma(bi)-sigma(|ai-x|)
sigma(bi)是已知的
所以我们需要求最小的sigma(|ai-x|)
然后就可以对于位置进行dp
dp[i][j]代表执行第i个事件时在第j位置上最小的和
因为每秒可以移动d个单位
所以假设当前第i个事件和i-1个事件相差一秒
我们就需要求
dp[i][j]=min(dp[i-1][k]+|ai-j|)
Left<=k<=right
left=j-d
Right=j+d
我们找的是最小的dp[i-1][k]
而且每次j移动的时候需要去掉一些dp[i-1][k]
所以这时候就可以对dp[i-1][k]维护一个单调队列
因为i和j太大,所以用滚动数组进行dp
然后就划划水,就A了
#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define lowbit(x) (x&(-x))typedef long long LL;const int maxn = 150005;const int inf=(1<<28)-1;LL dp[2][maxn];pair<LL,LL>Par[maxn];deque<pair<LL,int> >Que;int main(){ int n,m,d; scanf("%d%d%d",&n,&m,&d); LL ans=0; for(int i=0;i<m;++i) { LL x; scanf("%lld%lld%lld",&Par[i].second,&x,&Par[i].first); ans+=x; } sort(Par,Par+m); for(int i=1;i<=n;++i) dp[0][i]=abs(i-Par[0].second); //for(int i=1;i<=n;++i) printf("%lld ",dp[0][i]);printf("\n"); int now=1; for(int i=1;i<m;++i) { LL k=Par[i].first-Par[i-1].first; k*=d; LL LastLeft=1; LL LastRight=min((LL)n,k+1); //printf("***%lld %lld\n",LastLeft,LastRight); Que.clear(); for(int j=LastLeft;j<=LastRight;++j) { while(!Que.empty()&&Que.back().first>=dp[!now][j]) Que.pop_back(); Que.push_back(make_pair(dp[!now][j],j)); } for(int j=1;j<=n;++j) { LL Left=max(1LL,(LL)j-k); LL Right=min((LL)n,(LL)j+k); if(Right!=LastRight) { LL tmp=dp[!now][Right]; while(!Que.empty()&&Que.back().first>=tmp) Que.pop_back(); Que.push_back(make_pair(tmp,Right)); } while(!Que.empty()&&Que.front().second<Left) Que.pop_front(); dp[now][j]=abs(Par[i].second-j)+Que.front().first; LastRight=Right;LastLeft=Left; } //for(int j=1;j<=n;++j) printf("%lld ",dp[now][j]);printf("\n"); now=!now; } LL res=inf; for(int i=1;i<=n;++i) res=min(res,dp[!now][i]); printf("%lld\n",ans-res); return 0;}
0 0
- 单调队列1007 Codeforces Round #219 (Div. 1) 372C. Watching Fireworks is Fun
- Codeforces Round #219 (Div. 2) E. Watching Fireworks is Fun
- codeforces 372C Watching Fireworks is Fun 单调队列优化dp
- DP训练 codeforces 372C Watching Fireworks is Fun [单调队列优化dp]
- CodeForce Round 219 Div2 E Watching Fireworks is Fun 单调队列DP
- Codeforces —— 372C Watching Fireworks is Fun
- Codeforces 373E Watching Fireworks is Fun【思维+单调队列优化Dp+滚动数组】
- CF 372C Watching Fireworks is Fun
- C. Watching Fireworks is Fun---dp
- CF372C Watching Fireworks is Fun(dp+双端队列)
- Codeforces Round #219 (Div. 2)--C. Counting Kangaroos is Fun
- Codeforces Round #219 (Div. 1) A. Counting Kangaroos is Fun
- Codeforces Round #219 (Div. 2) Counting Kangaroos is Fun
- Codeforces Round #219 (Div. 2) D. Counting Rectangles is Fun
- Codeforces Round #219 (Div. 1) A. Counting Kangaroos is Fun 【二分】
- Codeforces #219 (Div. 2) C. Counting Kangaroos is Fun
- Codeforces Round #219 (Div. 2)A. Collecting Beats is Fun
- Codeforces Round #344 (Div. 2)-C. Report(单调栈)
- GET和POST
- 单调队列1006 POJ 1821 Fence
- TreeSet重写比较器按照字符串长度排序
- 在ubuntu中用vscode编译调试C\C++
- 各个平台支持的Cocos2d-x最大纹理尺寸
- 单调队列1007 Codeforces Round #219 (Div. 1) 372C. Watching Fireworks is Fun
- Android 微博分享及其注意事项
- 关于PowerImageView使用问题总结
- javascript
- Codeforces Round #362 (Div. 1) B Puzzles
- poj 2115扩展欧几里得总结
- 85. Maximal Rectangle
- Android GridView设置宽高,即item宽度高度
- 总有一个在路上