ZOJJ Watashi's BG3631

开始感觉这题像一个大数01背包,好像遇见过好几道这样的题,但一直不会写。。

今天看了slon神的题解,感觉很神奇!

他的把n个点分成两堆,然后再分别枚举,最后再利用贪心组合。

先写个随笔放这,防止以后忘记了,o(︶︿︶)o 唉,记性不好是硬伤啊!!!

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1<<16
using namespace std;
int g[2][MAXN];
int val[50];
int N,M;
int top1,top2;
int main()
{
 //   freopen("in.txt","r",stdin);
    while(scanf("%d%d",&N,&M)==2){
        int l=N/2;
        int r=N-l;
        top1=0,top2=0;
        for(int i=0;i<N;i++){
            scanf("%d",&val[i]);
        }
        for(int i=0;i<1<<l;i++){
            int t=i,k=0,s=0;
            while(t){
                if(t&1)s+=val[k];
                t=t>>1;
                k++;
            }
            g[0][top1++]=s;
        }
        for(int i=0;i<1<<r;i++){
            int t=i,k=l,s=0;
            while(t){
                if(t&1)s+=val[k];
                t=t>>1;
                k++;
            }
            g[1][top2++]=s;
        }
        sort(g[0],g[0]+top1);
        sort(g[1],g[1]+top2);
        int j=top2-1;
        int ans=0;
        for(int i=0;i<top1;i++){
            for(;j>=0;j--){
                if(g[0][i]+g[1][j]<=M){
                    ans=max(ans,g[0][i]+g[1][j]);
                    break;
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/arbitrary/p/2615468.html