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场考试 每场考试有如下信息 ...
随机推荐
- 微信小程序开发——以简单易懂的浏览器页面栈理解小程序的页面路由
前言: 对于小程序的页面路由,如果没有一定开发经验的话,理解起来还是会有些困难的.哪怕是有一定小程序开发经验的开发者,能够完全理解掌握的恐怕也不多. 这里就以另外一种方式来详细的介绍小程序的页面栈及路 ...
- 分布式大数据多维分析(OLAP)引擎Apache Kylin安装配置及使用示例【转】
Kylin 麒麟官网:http://kylin.apache.org/cn/download/ 关键字:olap.Kylin Apache Kylin是一个开源的分布式分析引擎,提供Hadoop之上的 ...
- java中元注解有四个
@Retention @Target @Document @Inherited: @Retention:注解的保留位置 @Retention(RetentionPolicy.SOURCE) // ...
- java_3选择与循环
1.三种执行顺序(流程控制语句) 在Java中,有三种执行结构,第一种:顺序结构.第二种:循环结构.第三种:选择结构. 2.顺序结构 自上而下,顺序执行. 3.循环结构 (1)while语句 初始化表 ...
- linux下Redis主从复制
Redis的主从配置比起MySQL主从配置简单多了,而且Redis主从复制中一个主服务可以有多个从服务,一个从服务又可以有多个从服务. MySQL主从配置http://www.cnblogs.com/ ...
- mysql 定时任务的使用
mysql5.1.6增加了一个事件调度器(Event Scheduler),可以做定时任务(定时删除记录,定时数据统计),取代之前系统的计划任务.mysql事件调度器可以精确到每秒执行一个任务. 事件 ...
- 10.15 JS日记
1.JS 介绍 js的全称是JavaScript,它是一门前台语言 Java是一门后台语言 ,它们两个之间毫无关系 JavaScript的作者是布兰登,艾奇 前台语言:运行在客户端 后台语言:与数据库 ...
- Java 和 Javascript的关系
写这篇文章是因为看到有人问这个问题,在想怎么会有这种SB问题,不过想想当初SB的我貌似也搞不清两者的关系,认知还是需要一个过程. 然后看到比较经典的回答有:Java 和Javascript的关系就像雷 ...
- Pandas设置值
1.创建数据 >>> dates = pd.date_range(', periods=6) >>> df = pd.DataFrame(np.arange(24) ...
- POJ1236或洛谷2746或洛谷2812 Network of Schools
POJ原题链接 洛谷2746原题链接 洛谷2812(加强版)原题链接 显然在强连通分量里的所有学校都能通过网络得到软件,所以我们可以用\(tarjan\)求出强连通分量并缩点,统计缩点后每个点的入度和 ...