Codeforces Round #541 (Div. 2) G dp + 思维 + 单调栈 or 链表 (连锁反应)
https://codeforces.com/contest/1131/problem/G
题意
给你一排m个的骨牌(m<=1e7),每块之间相距1,每块高h[i],推倒代价c[i],假如\(abs(i-j)<h[i]\),那么向j方向推倒i,j也会倒,问选择任意数量骨牌向任意方向推到,使得全部骨牌都倒下的代价最小
题解
- 连锁反应可以用单调栈或者链表模拟
- 定义dp[i]为推倒a[i,m]的最小代价
- 对于每个i,有两种选择:
- 向左推:\(dp[l[i]+1]=min(dp[l[i]+1],dp[i+1]+c[i])\)
- 向右推:\(dp[i]=min(dp[i],rf[i]+c[i]),rf[i]\),\(rf[i]\)为推倒i能到达的位置上最小dp值
- 单调栈写法很难懂
代码
链表写法
#include<bits/stdc++.h>
#define ll long long
#define mxN 300005
#define mxM 10000005
#define inf 0x3f3f3f3f
using namespace std;
ll n,m,i,j,k,N,q,x,y,p;
int l[mxM],h[mxM],r[mxM];
vector<array<int,2>>a[mxN];
ll rf[mxM],f[mxM],c[mxM];
int main(){
cin>>n>>m;
for(i=0;i<n;i++){
scanf("%lld",&N);
a[i].resize(N);
for(j=0;j<2;j++)
for(k=0;k<N;k++)
scanf("%d",&a[i][k][j]);
}
cin>>q;
for(i=0;i<q;i++){
scanf("%lld%lld",&x,&y);
for(j=0;j<a[x-1].size();j++,p++){
h[p]=a[x-1][j][0];
c[p]=a[x-1][j][1]*y;
l[p]=p-1;
while(l[p]>=0&&p-l[p]<h[p])
l[p]=l[l[p]];
}
}
memset(f,inf,sizeof(f));
f[m]=0;
for(i=m-1;i>=0;i--){
rf[i]=f[i+1];
r[i]=i+1;
while(r[i]<m&&r[i]-i<h[i]){
rf[i]=min(rf[r[i]],rf[i]);
r[i]=r[r[i]];
}
f[l[i]+1]=min(f[l[i]+1],f[i+1]+c[i]);
f[i]=min(f[i],rf[i]+c[i]);
}
cout<<f[0];
}
单调栈写法
#include<bits/stdc++.h>
#define ll long long
#define mxN 300005
#define mxM 10000005
#define inf 0x3f3f3f3f
using namespace std;
ll n,m,i,j,k,N,q,x,y,p,l,r;
int h[mxM],cnt[mxM];
vector<array<int,2>>a[mxN];
ll rf[mxM],f[mxM],c[mxM],val;
int main(){
cin>>n>>m;
for(i=0;i<n;i++){
scanf("%lld",&N);
a[i].resize(N);
for(j=0;j<2;j++)
for(k=0;k<N;k++)
scanf("%d",&a[i][k][j]);
}
cin>>q;
for(i=0;i<q;i++){
scanf("%lld%lld",&x,&y);
for(j=0;j<a[x-1].size();j++){
h[++p]=a[x-1][j][0];
c[p]=a[x-1][j][1]*y;
}
}
stack<array<ll,2>>s1;
stack<ll>s2;
s1.push({m+1,0});
s2.push(1e17);
//memset(f,inf,sizeof(f));
for(i=m;i>=1;i--){
r=min(m,i+h[i]-1);
while(r>=s1.top()[0])s1.pop();
cnt[s1.top()[0]-1]++;
s1.push({i,0});
}
while(!s1.empty())s1.pop();
s1.push({0,0});
for(i=1;i<=m;i++){
l=max(1ll,i-h[i]+1);
val=f[i-1];
while(l<=s1.top()[0]){
val=min(s1.top()[1],val);
s1.pop();
}
s1.push({i,val});
s2.push(min(s2.top(),f[i-1]+c[i]));
f[i]=min(s2.top(),val+c[i]);
for(j=0;j<cnt[i];j++)s2.pop();
}
cout<<f[m];
}
Codeforces Round #541 (Div. 2) G dp + 思维 + 单调栈 or 链表 (连锁反应)的更多相关文章
- Codeforces Round #541 (Div. 2) E 字符串 + 思维 + 猜性质
https://codeforces.com/contest/1131/problem/D 题意 给你n个字符串,字符串长度总和加起来不会超过1e5,定义字符串相乘为\(s*s1=s1+s[0]+s1 ...
- Codeforces Round #333 (Div. 1)--B. Lipshitz Sequence 单调栈
题意:n个点, 坐标已知,其中横坐标为为1~n. 求区间[l, r] 的所有子区间内斜率最大值的和. 首先要知道,[l, r]区间内最大的斜率必然是相邻的两个点构成的. 然后问题就变成了求区间[l, ...
- Codeforces Round #541 (Div. 2)
Codeforces Round #541 (Div. 2) http://codeforces.com/contest/1131 A #include<bits/stdc++.h> us ...
- Codeforces Round #582 (Div. 3)-G. Path Queries-并查集
Codeforces Round #582 (Div. 3)-G. Path Queries-并查集 [Problem Description] 给你一棵树,求有多少条简单路径\((u,v)\),满足 ...
- Codeforces Round #346 (Div. 2) G. Fence Divercity dp
G. Fence Divercity 题目连接: http://www.codeforces.com/contest/659/problem/G Description Long ago, Vasil ...
- Codeforces Round #541 (Div. 2)题解
不知道该更些什么 随便写点东西吧 https://codeforces.com/contest/1131 ABC 太热了不写了 D 把相等的用并查集缩在一起 如果$ x<y$则从$ x$往$y$ ...
- Codeforces Round #547 (Div. 3) G 贪心
https://codeforces.com/contest/1141/problem/G 题意 在一棵有n个点的树上给边染色,连在同一个点上的边颜色不能相同,除非舍弃掉这个点,问最少需要多少种颜色来 ...
- Codeforces Round #546 (Div. 2) D 贪心 + 思维
https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则, ...
- Codeforces Round #481 (Div. 3) G. Petya's Exams
http://codeforces.com/contest/978/problem/G 感冒是真的受不了...敲代码都没力气... 题目大意: 期末复习周,一共持续n天,有m场考试 每场考试有如下信息 ...
随机推荐
- [LeetCode_98]Validate Binary Search Tree
题目链接 https://leetcode.com/problems/validate-binary-search-tree/ 题意 判断给定树是否是BST 思路 根据定义判断.递归. 代码 clas ...
- samrty模板变量操作符
count_sentences [计算句数],示例:{$smarty.get.name|count_sentences} count_words [计算词数],示例:{$smarty.get.name ...
- golang 创建一个简单的连接池,减少频繁的创建与关闭
一.连接池的描述图片如下: 二.连接池代码如下: package main; import ( "time" "sync" "errors" ...
- BCH/BSV coin split troubleshooting
BCH/BSV coin split troubleshootingMark Lundeberg 2018 November 27ResourcesGuides:Locktime based spli ...
- 异常处理 day 30
异常处理 一 错误和异常 二 异常处理 2.1 什么是异常处理? 2.2 为何要进行异常处理? 2.3 如何进行异常处理? 三 什么时候用异常处理 异常和错误 part1:程序中难免出现错误,而错误分 ...
- 迭代器、生成器 day13
一 迭代器 迭代器的由来pythone2.2引进的,是一种序列(也是一种数据类型),也是为类对象提供一个序列的入口. for 循环str list tuple dict set 文件句柄可迭代: s ...
- PAT 1016 部分A+B(15)(C++&JAVA&&Python)
1016 部分A+B(15 分) 正整数 A 的"DA(为 1 位整数)部分"定义为由 A 中所有 DA 组成的新整数 PA.例如:给定 A=3862767,D ...
- jsonp,ajax,json问题
JSONP技术 JSONP是解决跨域问题的一种常见方式 跨域问题,因为浏览器有同源策略,所以当不同域间进行数据交互的时候就会出现跨域问题 同源策略:只有在同协议.同域名.同端口的情况下才能进去数据交互 ...
- 关于发件人地址会自动增加BATV及prvs的问题处理方法
问题描述: 发现Exchange 2010往外发邮件时,有些用户的发件人地址会自动增加BATV= 及 prvs=绪如,这些的特定字符,变成型如prvs=123456=example@example.c ...
- 基于稀疏表(Sparse Table)的RMQ(区间最值问题)
在RMQ的其他实现方法中,有一种叫做ST的算法比较常见. [构建] dp[i][j]表示的是从i起连续的2j个数xi,xi+1,xi+2,...xi+2j-1( 区间为[i,i+2j-1] )的最值. ...