HDU 3448 Bag Problem
DFS+剪枝
有一些比较强大的剪枝,先对输入的价值排序,如果最小的超过了限制,直接输出0,如果价值最大的LimN个加起来没有超过限制,那也直接输出答案,剩下的就是常规的DFS。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int maxn=50; int LimN; long long LimV; int N; long long v[maxn]; long long ans; void dfs(int now,int tot,long long sum) { if(sum>ans) ans=sum; if(now==N) return; if(tot+1>LimN) return; if(sum+v[now]>LimV) return; dfs(now+1,tot+1,sum+v[now]); dfs(now+1,tot,sum); } int main() { while(~scanf("%d%lld",&LimN,&LimV)) { scanf("%d",&N); for(int i=0; i<N; i++) scanf("%lld",&v[i]); sort(v,v+N); long long k=0; for(int i=N-1;i>=N-min(LimN,N);i--) k=k+v[i]; if(v[0]>LimV) { printf("0\n"); continue; } if(k<=LimV) { printf("%lld\n",k); continue; } ans=0; dfs(0,0,0); printf("%lld\n",ans); } return 0; }