ZOJ-J - Watashi's BG-3631
开始感觉这题像一个大数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; }