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;
}

浙公网安备 33010602011771号