和Leo一起做爱贪心的好孩子之PA2014 Final Zarowki

版权声明:LeoJAM Presents https://blog.csdn.net/fcb_x/article/details/82874516

有n个房间和n盏灯,你需要在每个房间里放入一盏灯。每盏灯都有一定功率,每间房间都需要不少于一定功率的灯泡才可以完全照亮。 
你可以去附近的商店换新灯泡,商店里所有正整数功率的灯泡都有售。但由于背包空间有限,你至多只能换k个灯泡。 
   你需要找到一个合理的方案使得每个房间都被完全照亮,并在这个前提下使得总功率尽可能小。

不错的贪心。

首先考虑当前灯泡跟新尽可能更新的

然后每个不能的自然就是其的值。

然后如果k还有剩的你在开一个multiset存差

然后从大到小维护

这个贪心似乎可以反悔?雾

HZY费用流72分

注意开LL

不用堆是因为:堆不能回收内存(它不是用vector写的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
using namespace std;
typedef int INT;
#define int long long
const int N=1e6+10;
multiset<int>Up,Down;
int A[N];
int B[N];
int n,k;
int ans=0;
INT main(){
	freopen("zarowki.in","r",stdin);
	freopen("zarowki.out","w",stdout);
	scanf("%lld%lld",&n,&k);	
	for(int i=1;i<=n;++i){
		scanf("%lld",&B[i]);
	}
	for(int i=1;i<=n;++i){
		scanf("%lld",&A[i]);
		Up.insert(A[i]);
	}
	sort(B+1,B+1+n);
	for(int i=1;i<=n;++i){
		multiset<int>:: iterator It;
		It=Up.upper_bound(B[i]);
		if(It==Up.begin())continue;
		--It;
		int x=*It;
		Up.erase(Up.find(x));
		ans+=B[i];
		Down.insert(B[i]-x);
	}
	if(Up.size()>k)cout<<"NIE";
	else{
		int cnt=0;
		multiset<int>:: iterator It;
		It=Up.begin();
		for(;It!=Up.end();++It){
			ans+=*It;
			++cnt;
		}
		for(int i=cnt+1;i<=k;++i){
			It=Down.end();
			--It;
			int x=*It;
			ans-=x;
			Down.erase(Down.find(x));
		}
		cout<<ans;
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/82874516