CF#1515C (高塔贪心)

题目链接

https://codeforces.com/contest/1515/problem/C

算法思路

将id数组排序,按照方块的高度排序{return a[c]>a[d]},优先放最大的
优先队列,当前塔中,高度最低的塔,放上去

然后遍历完所有的之后,再判断其中最高的塔和最低的塔的高度查是否大于h即可

证明:贪心策略,矛盾法
答案不存在NO,就离谱
如果存在的话,因为初始条件均小于h,所以差值也就小于h,如果最后出现了大于等于h的情况,就说明差值是两个方块,这也就和贪心法矛盾,所以答案必然是YES

代码实现

#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
#define el '\n'
#define cl putchar('\n')
#define pb push_back
#define fir first
#define sec second

typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vci;
typedef map<int,int> mii;
typedef mii::iterator mii_it;
typedef mii::reverse_iterator mii_rit;

const int N=1e5+10,M=1e3+10;

int T,n,m,x,y,k,h;
;int v[N];
int mx,mi;
bool cmp(int c,int d){
	return v[c]>v[d];
}
void get(vci p){
	for(int i=1;i<p.size();i++){
		if(mx<p[i]){
			mx=p[i];
		}
		if(mi>p[i]){
			mi=p[i];
		}
	}
}
int main() {
	cin.tie(0);
	cout.tie(0);
	
	cin>>T;
	while(T--) {
		priority_queue<pii> q;
		
		cin>>n>>m>>h;
		
		vci t(n,0);
		for(int i=0;i<n;i++){
			cin>>v[i];
		}
		for(int i=1;i<=m;i++)q.push({0,i});
		for(int i=0;i<t.size();i++){
			t[i]=i;
//			cout<<t[i]<<" "; 
		}
		sort(t.begin(),t.end(),cmp);
		vci w(n);
		vci pre(m+1);
		for(int i=0;i<n;i++){
			pii now=q.top();
			q.pop(); 
			now.first-=v[t[i]];
			w[t[i]]=now.sec;
			q.push(now);
		}
		for(int i=0;i<n;i++){
			pre[w[i]]+=v[i];//建立高塔 
		}
		mx=INT_MIN,mi=INT_MAX;
		get(pre);
		if(mx-mi<=h){
			cout<<"YES"<<el;
			for(int i=0;i<n;i++){
				cout<<w[i]<<" ";
			} 
			cout<<el;
		}
		else cout<<"NO"<<el;
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值