CF1870D Prefix Purchase 题解

CF1870D Prefix Purchase 题解

CnBlogs链接

题意#

你有一个长为 n 的数组 a,初始全为 0

初始你有 k 个硬币。你可以花费 ci 个硬币让 a 数组 [1,i] 的前缀的值 +1。你要保证自己的硬币数量始终非负。

a 数组的字典序最大是多少。

思路#

萌新竟然能切 D 了!!!

首先考虑 dp。记 fi 表示花费 i 个硬币时,a1 最大是多少。但是要最大化字典序,所以我们需要尽可能选 i 较大的 ci。所以我们记 gi 表示 fi 是用哪种硬币转移过来的。跑完全背包即可。复杂度 O(nk)

发现这样复杂度过于炸裂。我们考虑 dp 做的是什么,就是优先选尽可能多的 a1,然后尽可能多的选择 a2,以此类推。

考虑如何选尽可能多的 a1。肯定是选择全局最小值啊!考虑如何选尽可能多的 a2。肯定是用后缀最小值替换掉上面对 a1 贡献的一些 c 啊!所以我们用堆维护已经选过的 c,每次用 c 的后缀最小值去尝试替换。

复杂度 O(nlogn)

代码#

萌新代码有点丑,大佬不要嫌弃

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
	int ans=0;bool op=0;char ch=getchar();
	while(ch<'0'||'9'<ch){if(ch=='-')op=1;ch=getchar();}
	while('0'<=ch&&ch<='9'){ans=(ans<<1)+(ans<<3)+(ch^48);ch=getchar();}
	if(op)return -ans;
	return ans;
}
const int maxn=2e5+10;
int n,k;
int c[maxn];
int mn[maxn];//c的后缀最小值的下标
int a[maxn];//最终形成的序列
struct node{
	int val,cnt,id;//这个c的权值、数量、编号
	bool operator < (const node &cmp)const{
		return val<cmp.val||(val==cmp.val&&id>cmp.id);
	}
};
priority_queue<node>q;
void real_main(){
	//read
	n=read();
	for(int i=1;i<=n;i++)c[i]=read();
	k=read();
	//init
	//清空
	while(!q.empty())q.pop();
	memset(a,0,sizeof(int)*(n+2));
	mn[n]=n;
	for(int i=n-1;i>=1;i--)mn[i]=c[i]<c[mn[i+1]]?i:mn[i+1];//处理后缀最小值的下标
	q.push((node){0,(int)2e9,0});//加一个0,方便处理
	//solve
	for(int i=1;i<=n;i++){
		node awa=(node){c[mn[i]],0,mn[i]};
		while(!q.empty()){
			node now=q.top();q.pop();
			int dif=c[mn[i]]-now.val;
			if(!dif){//如果不用替换,那么直接退出
				q.push(now);//拿出来的没有动,放回去
				break;
			}
			int tmp=min(k/dif,now.cnt);//计算一下可以替换掉几个
			now.cnt-=tmp;
			awa.cnt+=tmp;
			a[now.id]-=tmp;
			a[mn[i]]+=tmp;
			k-=dif*tmp;
			if(now.cnt)q.push(now);
			if(!tmp)break;//已经不能替换了,退出
		}
		if(awa.cnt)q.push(awa);
	}
	for(int i=n;i>=1;i--)a[i]=a[i+1]+a[i];//我们的a是一个后缀和,算出来
	for(int i=1;i<=n;i++)cout<<a[i]<<' ';
	puts("");
}
signed main(){
	int T=read();//多组数据
	while(T--)real_main();
	return 0;
}s
posted @   洛谷Augury  阅读(85)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示