题目:有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;
}