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 链表 (连锁反应)的更多相关文章

  1. Codeforces Round #541 (Div. 2) E 字符串 + 思维 + 猜性质

    https://codeforces.com/contest/1131/problem/D 题意 给你n个字符串,字符串长度总和加起来不会超过1e5,定义字符串相乘为\(s*s1=s1+s[0]+s1 ...

  2. Codeforces Round #333 (Div. 1)--B. Lipshitz Sequence 单调栈

    题意:n个点, 坐标已知,其中横坐标为为1~n. 求区间[l, r] 的所有子区间内斜率最大值的和. 首先要知道,[l, r]区间内最大的斜率必然是相邻的两个点构成的. 然后问题就变成了求区间[l, ...

  3. Codeforces Round #541 (Div. 2)

    Codeforces Round #541 (Div. 2) http://codeforces.com/contest/1131 A #include<bits/stdc++.h> us ...

  4. Codeforces Round #582 (Div. 3)-G. Path Queries-并查集

    Codeforces Round #582 (Div. 3)-G. Path Queries-并查集 [Problem Description] 给你一棵树,求有多少条简单路径\((u,v)\),满足 ...

  5. Codeforces Round #346 (Div. 2) G. Fence Divercity dp

    G. Fence Divercity 题目连接: http://www.codeforces.com/contest/659/problem/G Description Long ago, Vasil ...

  6. Codeforces Round #541 (Div. 2)题解

    不知道该更些什么 随便写点东西吧 https://codeforces.com/contest/1131 ABC 太热了不写了 D 把相等的用并查集缩在一起 如果$ x<y$则从$ x$往$y$ ...

  7. Codeforces Round #547 (Div. 3) G 贪心

    https://codeforces.com/contest/1141/problem/G 题意 在一棵有n个点的树上给边染色,连在同一个点上的边颜色不能相同,除非舍弃掉这个点,问最少需要多少种颜色来 ...

  8. Codeforces Round #546 (Div. 2) D 贪心 + 思维

    https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则, ...

  9. Codeforces Round #481 (Div. 3) G. Petya's Exams

    http://codeforces.com/contest/978/problem/G 感冒是真的受不了...敲代码都没力气... 题目大意: 期末复习周,一共持续n天,有m场考试 每场考试有如下信息 ...

随机推荐

  1. UmBasketella

    UmBasketella http://poj.org/problem?id=3737 Time Limit: 1000MS   Memory Limit: 65536K Total Submissi ...

  2. C# 页面向controller中跳转匹配方法的时候,当controller中有两个重载方法时候,不发生跳转

    在ajax中的URL跳向controller一个方法时候,controller中有两个重载的方法,ajax不发生跳转,当删除另外一个方法之后,正常跳转. 不知道,是我自己写的有问题,还是control ...

  3. Vue Baidu Map 插件的使用

    最近在做一个项目,技术采用的是Vue.js套餐,有个百度地图的需求,当时,大脑宕机,立马去引入百度地图API,当时想到两种方法,一种是在index.html中全局引入js,此法吾不喜,就采用了第二种异 ...

  4. 使用vue-cli快速搭建大型单页应用

    前言: 经过一段时间angular的洗礼之后 ,还是决定回归Vue.现就vue安装.工程搭建.常用依赖安装直至开发挣个流程做一整理,希望对初学者有所帮助. 前提条件: 对 Node.js 和相关构建工 ...

  5. Linux 下 mysql的基本配置

    Linux 下 mysql的基本配置 2013年02月27日 ⁄ MySQL ⁄ 共 3000字 ⁄ 暂无评论 ⁄ 被围观 2,483 views+ 1. Linux mysql安装:    $ yu ...

  6. 【centos】centos安装g++

    gcc在Centos下的安装:使用的是以下语句:yum install gcc 以为安装g++,类似的应该使用:yum install g++ 可是提示:command is not found 查询 ...

  7. 关于gcc、make和CMake的区别

    CMake是一种跨平台编译工具,比make更为高级,使用起来要方便得多.CMake主要是编写CMakeLists.txt文件,然后用cmake命令将CMakeLists.txt文件转化为make所需要 ...

  8. mvc下添加 EntityFramework的引用

    首先   打开工具-扩展和更新-联机-Visual Studio库,找到NuGet Package Manager 检查是否 安装,如果没有安装 先安装插件 安装成功后,右键点击‘引用’,如下图 然后 ...

  9. 30-算法训练 最短路 spfa

    http://lx.lanqiao.cn/problem.page?gpid=T15 算法训练 最短路   时间限制:1.0s   内存限制:256.0MB        问题描述 给定一个n个顶点, ...

  10. 29-jsp中用js进行时间格式转化

    CST可以为如下4个不同的时区的缩写: 美国中部时间:Central Standard Time (USA) UT-6:00 澳大利亚中部时间:Central Standard Time (Austr ...