首页 > 其他分享 >1

1

时间:2023-12-27 22:22:07浏览次数:17  
标签: min int leq 怪物 药水 打败

2f7f2e7e-2009-424e-a824-a590d1cd8234

[题目翻译]

问题陈述

高桥将踏上冒险之旅。

在探险过程中,会发生 \(N\) 个事件。\(i\)-th 事件 \((1\leq i\leq N)\) 由一对整数 \((t _ i,x _ i)\) 表示。\((1\leq t _ i\leq 2,1\leq x _ i\leq N)\) 并如下所示:

  • 如果 \(t _ i=1\),他找到了一个 \(x _ i\) 类型的药水。他可以选择捡起或丢弃。
  • 如果是 \(t _ i=2\),他将遇到一只 \(x _ i\) 类型的怪物。如果他有\(x _ i\)型药水,他可以使用一种药水击败怪物。如果他没有打败怪物,他就会被打败。

判断他是否可以打败所有怪物而不被打败。

如果他无法打败所有怪物,则打印 -1

否则,让\(K\)成为他在冒险过程中拥有的最大药水数量。让 \(K _ {\min}\) 成为 \(K\) 在所有策略中不会被击败的最小值。打印 \(K _ {\min}\) 的值以及高桥实现 \(K _ {\min}\) 的行动。

[思路]:

有一个贪心策略:每次选在当前怪物前且距离最短的未被使用过的同种药水一定最优

考虑感性证明:

如果选第一个出现的同种药水,则这个药水可能会让他一直拿着药水而不用,会使在单位时间里所拥有的最大数量增加。

因为下标本身就有单调性,所以直接用栈维护每种药水出现的位置即可,遇到怪物取出同种药水栈顶就代表取走这个位置的药水,用数组存下来最终最大数量模拟一遍就好啦。

考场我急了,所以吗,码风奇丑且用的大根堆,后来才发现下标本身就有单调性。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+5;
int n,t[N],a[N];
int ans[N],s[N],vis[N],sum,p;
priority_queue<int> q[N];
signed main(){
	cin >> n;
	for(int i=1;i<=n;i++){
		cin >> t[i] >> a[i];
		if(t[i]==1) q[a[i]].push(i);
		else{
			if(q[a[i]].empty()){//空了就代表在这个怪物前没有能杀死这个怪物的药水了。
				puts("-1");
				return 0;
			}
			ans[q[a[i]].top()]=1;
			q[a[i]].pop();
		}
	}
	for(int i=1;i<=n;i++){
		if(ans[i]==1) vis[a[i]]++,sum++;
		if(t[i]==2){
			vis[a[i]]--,sum--;
		}
		p=max(p,sum);
	}
	cout << p << "\n";
	for(int i=1;i<=n;i++){
		if(t[i]==2) continue;
		cout << ans[i] << ' ';
	}
	return 0;
}

标签:,min,int,leq,怪物,药水,打败
From: https://www.cnblogs.com/muleaf/p/17931565.html

相关文章