打卡信奥刷题(3403)用C++实现信奥题 P10051 [CCO 2022] Rainy Markets

P10051 [CCO 2022] Rainy Markets

题目背景

由于数据包过大,本题无法上传全部数据。

题目描述

NNN 个公交车站,标号为 1,…,N1, \ldots, N1,,N。第 iii 个公交车站可以容纳 BiB_{i}Bi 个人。

对于每个 i∈{1,…,N−1}i \in\{1, \ldots, N-1\}i{1,,N1},有一条人行道连接公交车站 iii 和公交车站 i+1i+1i+1,中间有一个露天市场。第 iii 个市场有 UiU_{i}Ui 把雨伞出售,每把雨伞的价格为 111

现在,有 PiP_{i}Pi 个人在第 iii 个市场里面,所有的公交车站都是空的。

突然,天开始下雨,市场 iii 的每个人都必须在三种方案中选择一种:

  • 去公交车站 iii
  • 去公交车站 i+1i+1i+1
  • 留下来买一把雨伞。

如果一个人无法在某个公交车站下或者买一把雨伞,他们就会淋湿。

你需要回答如果在最优的安排方案下,能否确保每个人都能不被雨淋湿。如果是的话,你需要给出他们需要花费的最少的钱,以及每个人应该移动到哪个公交车站。

输入格式

第一行包含一个整数 NNN

第二行包含 NNN 个用空格分隔的整数 Bi (1≤i≤N)B_{i}\ (1 \leq i \leq N)Bi (1iN),表示公交车站 iii 的容量。

第三行包含 N−1N-1N1 个用空格分隔的整数 Pi (1≤i≤N−1)P_{i}\ (1 \leq i \leq N-1)Pi (1iN1),表示市场 iii 的人数。

第四行包含 N−1N-1N1 个用空格分隔的整数 Ui (1≤i≤N−1)U_{i}\ (1 \leq i \leq N-1)Ui (1iN1),表示市场 iii 出售的雨伞的数量。

输出格式

如果每个人都能在雨伞或公交车站下,输出 N+1N+1N+1 行:

  • 第一行输出一行 YES
  • 第二行输出一个整数,表示包含在雨伞上花费的最少的钱。
  • 接下来的 N−1N-1N1 行,每行输出三个用空格分隔的整数分别表示市场 i (1≤i≤N−1)i\ (1\leq i \leq N-1)i (1iN1) 移动到公交车站 iii 的人数,市场 iii 买雨伞的人数,市场 iii 移动到公交车站 i+1i+1i+1 的人数。

如果有多种合法方案,你可以输出任意一种。

否则,输出一行 NO

输入输出样例 #1

输入 #1

3
10 15 10
20 20
0 0

输出 #1

NO

输入输出样例 #2

输入 #2

3
10 15 10
20 20
0 11

输出 #2

YES
5
10 0 10
5 5 10

说明/提示

样例 1 解释

公交车站有 353535 个空位,没有雨伞出售,但市场有 404040 个人,所以答案是 NO

样例 2 解释

市场 111 中的 101010 个人会去公交车站 111,没有人会买雨伞,101010 个人会去公交车站 222

市场 222 中的 555 个人会去公交车站 222555 个人会留下来买雨伞,101010 个人会移动到公交车站 333

总共购买了 555 把雨伞,花费了 555

数据范围

对于所有的数据,有 2≤N≤1062 \leq N \leq 10^{6}2N1060≤Bi≤2⋅1090 \leq B_{i} \leq 2 \cdot 10^{9}0Bi21090≤Pi,Ui≤1090 \leq P_{i},U_{i} \leq 10^{9}0Pi,Ui109

子任务编号分值NNNBBBPPPUUU
1112020202≤N≤1062 \leq N \leq 10^{6}2N106$0 \leq B_{i} \leq 2 \cdot 10^{9} $0≤Pi≤1090 \leq P_{i} \leq 10^{9}0Pi109Ui=0U_{i}=0Ui=0
2222020202≤N≤20002 \leq N \leq 20002N20000≤Bi≤4000 \leq B_{i} \leq 4000Bi400$ 0 \leq P_{i} \leq 200$0≤Ui≤2000 \leq U_{i} \leq 2000Ui200
3332424242≤N≤40002 \leq N \leq 40002N40000≤Bi≤40000 \leq B_{i} \leq 40000Bi40000≤Pi≤20000 \leq P_{i} \leq 20000Pi20000≤Ui≤20000 \leq U_{i} \leq 20000Ui2000
4443636362≤N≤1062 \leq N \leq 10^{6}2N1060≤Bi≤2⋅1090 \leq B_{i} \leq 2 \cdot 10^{9}0Bi21090≤Pi≤1090 \leq P_{i} \leq 10^{9}0Pi1090≤Ui≤1090 \leq U_{i} \leq 10^{9}0Ui109

C++实现

#include<iostream>
using namespace std;
#define int long long 
const int N=1e6+10;
int n;
int b[N],p[N],u[N];
int f[N];
int l[N],r[N],buy[N];
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		scanf("%lld",&b[i]);
	}
	for(int i=1;i<n;i++){
		scanf("%lld",&p[i]);
	}
	for(int i=1;i<n;i++){
		scanf("%lld",&u[i]);
		if(u[i]+b[i]+b[i+1]<p[i]){
			cout<<"NO";
			return 0;
		}
	}
	for(int i=1;i<=n;i++){
		f[i]=max(0ll,b[i]-max(p[i-1]-f[i-1],0ll));
	}
	long long res=0;
	for(int i=n-1;i;i--){
		r[i]=min(p[i],b[i+1]-l[i+1]);
		p[i]-=r[i];
		l[i]=min(p[i],f[i]);
		p[i]-=l[i];
		buy[i]=min(p[i],u[i]);
		p[i]-=buy[i];
		l[i]+=p[i];
		res+=buy[i];
		if(l[i]>b[i]){
			cout<<"NO";
			return 0;
		}
	}
	printf("YES\n%lld\n",res);
	for(int i=1;i<n;i++){
		printf("%lld %lld %lld\n",l[i],buy[i],r[i]);
	}
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值