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 }
View Code

 

posted @ 2020-11-23 16:35  canwinfor  阅读(108)  评论(0)    收藏  举报