您的位置:首页 > 其它

BZOJ 3969: [WF2013]Low Power

2015-05-22 11:24 218 查看
题意:有n个机器,每个机器有2个芯片,每个芯片可以放k个电池。

每个芯片能量是k个电池的能量的最小值。两个芯片的能量之差越小,这个机器就工作的越好。现在有2nk个电池,已知它们的能量,我们要把它们放在n个机器上的芯片上,使得所有机器的能量之差的最大值最小。

数据范围比较大,所以肯定是贪心的思路。首先二分答案,将原序列排序后相邻两数的差值肯定比不相邻的要优,每找到一对相邻差值符合要求的,就相当于找到了一个电池上的最小值,从小往大找,如果找不满N个肯定不行,否则再从大往小将大芯片填充进去,只要任意时刻发现大芯片不够则不合法,否则肯定符合要求。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=1000000+10;
int a[maxn],n,k,mx,tot,cho[maxn];
bool check(int limi)
{
int cnt=0,num=0;
memset(cho,0,sizeof(cho));
for(int i=1;i<=tot-1;i++)
{
if(!cho[i]&&a[i+1]-a[i]<=limi&&cnt<n)
{
cho[i]=cho[i+1]=1;
cnt++;
}
}
if(cnt!=n) return false;
cnt=0;
for(int i=tot;i;i--)
{
if(!cho[i]) num++;
else
{
cnt++;
if(num<(k-1)*cnt) return false;
}
}
return true;
}
int main()
{
//freopen("3969.in","r",stdin);
//freopen("3969.out","w",stdout);
scanf("%d%d",&n,&k);tot=2*n*k;
for(int i=1;i<=tot;i++) scanf("%d",&a[i]),mx=max(mx,a[i]);
sort(a+1,a+tot+1);
int l=0,r=1000000000,ans;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))
{
r=mid-1;
ans=mid;
}
else l=mid+1;
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: