【暑假集训】HZOI2019 水站 多种解法
题目内容
- 已知有一个\(n\)层的水站:
- \(W_i\)表示未操作之前第\(i\)层的已有水量;
- \(L_i\)表示第\(i\)个水站能够维持或者储存的水的重量;
- 表示在第\(P_i\)层进行减压放水操作所需的费用.
- 被压减放水层所储存的所有水都将流向下一层。如果第\(i\)层的水量比\(L_i\)大,则这一层也会(自动)减压(不需要任何费用)。
- 现在想要使最后一层减压(第\(n\)级),求最少的花费。这个任务现在交给了你。
输入格式
- 每个输入的第一行包含一个自然数\(n(1\le n\le 150000)\)。
- 接下来\(n\)行每行包含\(3\)个数\(W_i,L_i,P_i(0\le W_i,L_i,P_i\le 15000)\)。
输出格式
- 第一行输出所需的最小费用。
- 第二行若干个整数,从小到大输出必须减压的层的编号。
样例输入
3
1000 1000 1
0 1000 2
2 10 100
样例输出
3
1 2
样例解释
给第一层和第二层减压即可。
代码
枚举+剪枝
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=150000+10;
int n,temp;
int w[maxn],l[maxn],p[maxn];
ll ans;
vector<int> res,mem;
void work(ll now){
mem.clear();
int x=now,tempw=w[now],tot=p[now],temp;
mem.push_back(now);
while(x<=n){
temp=w[++x]+tempw;
tempw=temp;
if(temp<=l[x]){
tot+=p[x];
mem.push_back(x);
}
if(tot>=ans)return;
}
if(tot<ans){
ans=tot;
res.clear();
for(int i=0;i<mem.size();i++){
res.push_back(mem[i]);
}
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&w[i],&l[i],&p[i]);
ans=p[n];res.push_back(n);
for(int i=1;i<n;i++)
work(i);
printf("%lld\n",ans);
for(int i=0;i<res.size();i++)
printf("%d ",res[i]);
return 0;
}
二分+差分
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=150000+10;
const ll INF=1e15;
int n;
ll ans=INF;
int w[maxn],l[maxn],p[maxn];
int c[maxn],sum[maxn];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&w[i],&l[i],&p[i]);
sum[i]=sum[i-1]+w[i];
}
for(int i=1;i<=n;i++){
int x=lower_bound(sum,sum+i+1,sum[i]-l[i])-sum;
x++;
c[x]+=p[i];
c[i+1]-=p[i];
}
int temp;
for(int i=1;i<=n;i++){
c[i]=c[i-1]+c[i];
if(ans>c[i]){
ans=c[i];
temp=i;
}
}
printf("%lld\n",ans);
int tot=0;
for(int i=temp;i<=n;i++){
tot+=w[i];
if(tot<=l[i])
printf("%d ",i);
}
return 0;
}
优先队列
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=150000+10;
const ll INF=1e15;
int n;
ll ans=INF;
int sum,num;
int w[maxn],l[maxn],p[maxn];
int s[maxn];
struct Node{
int sum,id;
bool operator < (const Node& x)const{
return x.sum<sum;
}
};
priority_queue<Node> q;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&w[i],&l[i],&p[i]);
for(int i=n;i>=1;i--)
s[i]=s[i+1]+w[i];
for(int i=n;i>=1;i--){
sum+=p[i];
while(!q.empty()){
Node t=q.top();
if(s[i]<=t.sum)break;
sum-=p[t.id];
q.pop();
}
Node cur;
cur.id=i;
cur.sum=l[i]+s[i+1];
q.push(cur);
if(ans>sum){
ans=sum;
num=i;
}
}
printf("%lld\n",ans);
sum = 0;
for(int i=num;i<=n;++i){
sum+=w[i];
if(sum<=l[i])printf("%d ",i);
}
return 0;
}
线段树
参见林dalao代码,%%%。
学长:不要用数据结构
\(rvalue\):不要无脑用数据结构
\(rvalue\)太巨辣我被爆锤辣QAQ
【暑假集训】HZOI2019 水站 多种解法的更多相关文章
- 暑假集训day1 水题 乘法最大
题目大意:有一个长度为N的字符串,要求用K个乘号将其分成K+1个部分,求各个部分相乘的最大值 输入:第一行输入N和K,第二行输入一个长度为N的字符串 算法分析 1. 这个题只是一个简单的dp(甚至连区 ...
- 暑假集训Day1 整数划分
题目大意: 如何把一个正整数N(N长度<20)划分为M(M>=1)个部分,使这M个部分的乘积最大.N.M从键盘输入,输出最大值及一种划分方式. 输入格式: 第一行一个正整数T(T<= ...
- 2015UESTC 暑假集训总结
day1: 考微观经济学去了…… day2: 一开始就看了看一道题目最短的B题,拍了半小时交了上去wa了 感觉自己一定是自己想错了,于是去拍大家都过的A题,十分钟拍完交上去就A了 然后B题写了一发暴力 ...
- 多种解法解决n皇后问题
多种解法解决n皇后问题 0x1 目的 深入掌握栈应用的算法和设计 0x2 内容 编写一个程序exp3-8.cpp求解n皇后问题. 0x3 问题描述 即在n×n的方格棋盘上,放置n个皇后,要求每 ...
- 【BZOJ4555】求和(多种解法混合版本)
[BZOJ4555]求和(多种解法混合版本) 题面 BZOJ 给定\(n\),求 \[f(n)=\sum_{i=0}^{n}\sum_{j=0}^{i}S(i,j)\times 2^j \times ...
- STL 入门 (17 暑假集训第一周)
快速全排列的函数 头文件<algorithm> next_permutation(a,a+n) ---------------------------------------------- ...
- 巴塞尔问题(Basel problem)的多种解法
巴塞尔问题(Basel problem)的多种解法——怎么计算\frac{1}{1^2}+\frac{1}{2^2}+\frac{1}{3^2}+\cdots112+122+132+⋯ ? (PS:本 ...
- 暑假集训Day2 互不侵犯(状压dp)
这又是个状压dp (大型自闭现场) 题目大意: 在N*N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. ...
- 【暑假集训】HZOI2019 Luogu P1006 传纸条 二三四维解法
写三次丢失两次,我谔谔,以后再不在博客园先保存我就去死 题目内容 洛谷链接 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学被安排坐成一个\(m\)行.\(n\ ...
随机推荐
- Docker 学习笔记一
Docker 学习笔记一 1.Docker是什么? Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源.让开发者打包他们的应用以及依赖包到一 ...
- 乔悟空-CTF-i春秋-Web-SQLi
2020.09.05 今天注定是高产的一天,这题真是坑,不看wp真的不会做,现在回头来复习一遍. 做题 题目 题目地址 做题 这题坑人的地方就在于重定向了两次,并且重要信息在第一次里藏着,第二次还给了 ...
- Linux实战(16):Centos history命令进阶
因在使用history命令是发现历史命令不同步,没有时间戳,在查看历史操作的时候很不方便,特查询了相关文档,发现可通过系统自带的logger来记录跟踪,历史命令执行的用户,时间,登录IP. vim / ...
- (数据科学学习手札95)elyra——jupyter lab最强插件
本文示例文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 jupyter lab是我最喜欢的编辑器,在过往 ...
- 本以为自己 MySQL 够牛逼了,直到亲自去阿里受虐了一次!
前言 众所周知,简历上“了解=听过名字:熟悉=知道是啥:熟练=用过:精通=做过东西”. 相信大家对于MySQL的索引都不陌生,索引(Index)是帮助MySQL高效获取数据的数据结构.索引作为MySQ ...
- spring boot之支持http和https并行(http不跳转)
首先需要去做个证书 yml配置文件中设置的是https监听端口 server: port: 10007 tomcat: basedir: /data/apps/temp #配置SSL ssl: key ...
- Java文件操作API功能与Windows DOS命令和Linux Shell 命令类比
Java文件操作API功能与Windows DOS命令和Linux Shell 命令类比: Unix/Linux (Bash) Windows(MS-DOS) Java 进入目录 cd cd - 创建 ...
- P4395 [BOI2003]Gem 气垫车
树形dp 首先,我们可以考虑dp,把这个问题看成一个树的染色问题,用dp[i][j]表示以i为根节点,将树染成第i种颜色的最小代价,那么我们可以得到j的最大值是(log(maxn)/log(2)+1) ...
- Laver 文件版本遍历器
系统简介 最近有个需求,需要罗列出各个目录中文件的信息,检索各类文件的最新版本.网上看了很多方式,但发现没有合适的.于是利用空余时间开始编写了一套文件遍历系统,如此便有了Laver(紫菜).Laver ...
- 如何使用 Python 進行字串格式化
前言: Python有几种方法可以显示程序的输出:数据可以以人类可读的形式打印出来,或者写入文件以供将来使用. 在开发应用程式时我们往往会需要把变数进行字串格式化,也就是说把字串中的变数替换成变量值. ...