NKOJ 1682 软件下载【二分答案】【贪心】

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define red(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;

const ll N=1e5+5;

ll n,m,sum,flag,a[N],b[N];

inline ll read() {
	ll x=0;char ch=getchar();bool f=0;
	while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?-x:x;
}

bool cmp(ll p,ll q) {
	return p>q;
}

void dfs(ll cur,ll tot,ll ret,ll lim) {
	if(flag) return ;
	
	if(tot==m||n-cur+1>=m-tot) {
		flag=1;return ;
	}
	
	if(cur==n||(n-cur-1)*lim+ret<sum) return ;
	
	rep(i,1,m) if(!b[i]&&ret>=a[i]) {
		b[i]=1;sum-=a[i];
		dfs(cur,tot+1,ret-a[i],lim);
		b[i]=0;sum+=a[i];
		if(flag) return ;
	}
	
	dfs(cur+1,tot,lim,lim);
}

int main() {
	n=read(),m=read();
	
	rep(i,1,m) a[i]=read(),sum+=a[i];
	
	sort(a+1,a+1+m,cmp);
	
	ll l=a[1],r=sum;
	
	while(l<=r) {
		flag=0;
		ll mid=l+r>>1;
		memset(b,0,sizeof(b));
		dfs(0,0,mid,mid);
		if(flag) r=mid-1;
		else l=mid+1; 
	}
	
	printf("%lld\n",l);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/83155564