题目:有n个物品,给出它们的k值,代表其重量为1/(2^k),要求把他们分成两组,每组重量和超过1/2,若可以输出方案
解:看题解写的,凑出1/2表示需要 1 个 k = 1 或者 2 个 k = 2 或者 4 个 k = 3 或者 ...以此类推下去
那么就可以将k值排一个序,cnt1,cnt2两个变量表示当前两组分别需要多少个pre(pre存储k = 1/2/3/...)值,然后每次更新pre值和cnt1 cnt2 值,当这两个变量都为0时表示有解
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
struct node
{
int x,id;
}a[maxn];
int T,n,cnt1,cnt2,pre;
int b[maxn];
bool flag;
bool cmp(node k,node l)
{
return k.x < l.x;
}
int main()
{
int tot = 0;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(b,0,sizeof(b));
for(int i = 0;i < n; ++i)
{
scanf("%d",&a[i].x);
a[i].id = i;
}
sort(a,a + n,cmp);
cnt1 = cnt2 = pre = 1;
flag = 1;
for(int i = 0;i < n; ++i)
{
while(cnt1 + cnt2 <= n - i && pre < a[i].x)
cnt1 <<= 1,cnt2 <<= 1,pre++;
if(cnt1 + cnt2 > n - i)
{
flag = 0;
break;
}
if(cnt1) cnt1--,b[a[i].id] = 1;
else cnt2--;
if(!cnt1 && !cnt2) break;
}
printf("Case %d: ",++tot);
if(!flag || cnt1 || cnt2) printf("NO\n");
else
{
printf("YES\n");
for(int i = 0;i < n; ++i) printf("%d",b[i]);
printf("\n");
}
}
return 0;
}