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场考试 每场考试有如下信息 ...
随机推荐
- Codeforces Beta Round #69 (Div. 2 Only)
Codeforces Beta Round #69 (Div. 2 Only) http://codeforces.com/contest/80 A #include<bits/stdc++.h ...
- tcp/ip通信第5期之服务器端程序
/* 此程序是tcp/ip通信服务器端程序,测试运行在redhat5上 重构readline函数,解决粘包问题——利用“\n”识别一个消息边界 */ #include<stdio.h> # ...
- mysql定时删除6个月前的表
查看定时是否开启: 查看event是否开启 : SHOW VARIABLES LIKE '%event_sche%'; 将事件计划开启 : ; 将事件计划关闭 : ; 代码: BEGIN -- 保存表 ...
- Windows系统制作Ubuntu启动U盘(命令行)
背景 现今Ubuntu系统的使用越来越多,考虑到日常办公还是用Windows系统,但开发的需求常常要有Linux系统.因此将Linux系统安装到U盘不失为一种好的选择.在Windows系统上制作Ubu ...
- Android Studio连接真机调试
1.安装配置Android studio2.2 2.下载手机驱动或者安装手机助手(360手机助手) 3.用手机助手连接用于调试的手机 注意手机要开启开发者模式->允许USB调试 4.查看手机连接 ...
- java_11接口
1接口的概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”. 接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成.这样将功能的定义 ...
- springmvc+logback项目的日志搭建
一.重写HTMLLayout 两个自定义类:LzhHTMLLayoutBase和LzhHTMLLayout LzhHTMLLayoutBase代码如下: package top.liaozhengha ...
- 使用 Spring 2.5 注释驱动的 IoC 功能
概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO ...
- Scrapy框架学习笔记
1.Scrapy简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网 ...
- How to Disable/Enable IP forwarding in Linux
This article describes how to Disable or Enable an IP forwarding in Linux. Current IP forwarding sta ...