AtCoder Beginner Contest 184 F - Programming Contest ###K //K
题目链接:https://atcoder.jp/contests/abc184/tasks/abc184_f
题意:给定 40个物品 容量1e9 的背包问题 重量与价值相等
思路: V很大的背包问题 但是N只有40 2^40 不行 考虑用折半枚举 降到2^20
分成两半 来暴力dfs 然后分别存在数组b和数组c 然后对数组c排序 然后遍历数组b 用二分找到 c中最大的能和b组合起来的方案数即可
时间复杂度 o(nlogn) n=2^20
我这里是用了二进制枚举来得到所有方案 然后再用双指针找到最大值
1 #include <bits/stdc++.h> 2 #define double long double 3 #define lb long double 4 #define ll long long 5 #define pi pair<int,int> 6 #define fi first 7 #define sc second 8 #define pb push_back 9 using namespace std; 10 const int maxn=3e5+10; 11 const int mod=1e9+7; 12 13 14 int n,t; 15 int a[100]; 16 vector<ll>c,d; 17 18 19 20 int main() 21 { 22 ios::sync_with_stdio(0); 23 cin.tie(0); 24 cin>>n>>t; 25 for(int i=0;i<n;i++) cin>>a[i]; 26 27 int lc=n/2; 28 int ld=n-n/2; 29 30 for(int i=0;i<1<<lc;i++) 31 { 32 ll tmp=0; 33 for(int j=0;j<lc;j++) 34 { 35 if(i>>j&1) tmp+=a[j]; 36 } 37 c.pb(tmp); 38 } 39 40 int p=n/2; 41 for(int i=0;i<1<<ld;i++) 42 { 43 ll tmp=0; 44 for(int j=0;j<ld;j++) 45 { 46 if(i>>j&1) tmp+=a[j+p]; 47 } 48 d.pb(tmp); 49 } 50 51 52 ll ans=0; 53 sort(c.begin(),c.end()); 54 sort(d.begin(),d.end()); 55 56 /*for(auto &v:c) cout<<v<<" debug"<<'\n'; 57 for(auto &v:d) cout<<v<<" debug2"<<'\n';*/ 58 59 for(int i=0,j=d.size()-1;i<c.size();i++) 60 { 61 while(j>0&&c[i]+d[j]>t) j--; 62 if(c[i]+d[j]<=t) ans=max(ans,c[i]+d[j]); 63 } 64 cout<<ans<<'\n'; 65 66 67 68 69 70 71 72 }

浙公网安备 33010602011771号