sgu171:Sarov zones(贪心)

题意:
有K个城市,第i城市至多有N[i]个人,每个城市有一个属性Q[i]。
对于N=∑N[i]个人,每个人有一个属性P[i]和价值W[i],把第i个人放进第j个城市中,当且仅当P[i]>Q[j]时,可以获得W[i]的价值,否则不获得价值。
求出满足价值和最大的人数分配方案。0<=N<=16000。
分析:
这道题不会dp,我等蒟蒻只能考虑贪心了。
先将每个人按W[i]值排序,从大到小处理。
对于当前的第i个人,放到当前①“还可容纳人的”②“Q[j]<P[i]的”③“最大的Q[j]所在的城市”。
条件①②判断是否可放,条件③使局部最优进而全局最优。
最后一些没放进任何城市的人随意插空放入即可。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXK = 109, MAXN = 16009;
int K, N[MAXK], Q[MAXK], P[MAXN];
struct weight
{
	int node, w;	
}W[MAXN];
int Sum;
int ans[MAXN];

bool cmp(const weight &A, const weight &B)
{
	return A.w > B.w;	
}

int main()
{
	cin >> K;
	for(int i = 1; i <= K; ++i) 
	{
		cin >> N[i];
		Sum += N[i];
	}
	for(int i = 1; i <= K; ++i) cin >> Q[i];
	for(int i = 1; i <= Sum; ++i) cin >> P[i];
	for(int i = 1; i <= Sum; ++i) 
	{
		cin >> W[i].w;
		W[i].node = i;
	}
	sort(W+1, W+Sum+1, cmp);
	for(int i = 1; i <= Sum; ++i)
	{
		int maxQ = -1, flag = -1;
		for(int j = 1; j <= K; ++j)
			if(Q[j] < P[W[i].node] && maxQ < Q[j] && N[j])
			{
				maxQ = Q[j];
				flag = j;	
			}
		ans[W[i].node] = flag;
		if(flag != -1) N[flag]--;
	}
	for(int i = 1; i <= Sum; ++i)
		if(ans[W[i].node] == -1)
			for(int j = 1; j <= K; ++j)
				if(N[j])
				{
					ans[W[i].node] = j;
					N[j]--;	
					break;
				}
	for(int i = 1; i <= Sum; ++i)
		cout << ans[i] << ' ';
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值