https://www.nowcoder.com/test/9763997/summary
牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为w。
牛牛家里一共有n袋零食, 第i袋零食体积为v[i]。
牛牛想知道在总体积不超过背包容量的情况下,他一共有多少种零食放法(总体积为0也算一种放法)。
输入描述:
输入包括两行
第一行为两个正整数n和w(1 <= n <= 30, 1 <= w <= 2 * 10^9),表示零食的数量和背包的容量。
第二行n个正整数v[i](0 <= v[i] <= 10^9),表示每袋零食的体积。
输出描述:
输出一个正整数, 表示牛牛一共有多少种零食放法。
输入例子1:
3 10 1 2 4
输出例子1:
8
例子说明1:
三种零食总体积小于10,于是每种零食有放入和不放入两种情况,一共有2*2*2 = 8种情况。
解析 我们一半一半枚举 枚举前一半 把每种情况的体积和存到数组ans里 再枚举后一半 当枚举到一种情况的体积和为sum时 二分查找数组ans中值小于等于w-sum的数量 加到答案里
AC代码
1 #include2 using namespace std; 3 typedef long long ll; 4 const ll mod=1000000007,maxn=5e4+50; 5 vector a,ans; 6 ll n,m; 7 int main() 8 { 9 while(cin>>n>>m) 10 { 11 a.clear(),ans.clear(); 12 for(int i=0; i ) 13 { 14 ll x; 15 cin>>x,a.push_back(x); 16 } 17 ll n1=n>>1,n2=n-n1; 18 for(int i=0; i<(1< ) 19 { 20 ll sum=0; 21 for(int j=0; j ) 22 if(i&(1< a[j]; 23 ans.push_back(sum); 24 } 25 sort(ans.begin(),ans.end()); 26 ll anss=0; 27 for(int i=0; i<(1< ) 28 { 29 ll sum=0; 30 for(int j=0; j ) 31 { 32 if(i&(1<<j)) 33 sum+=a[n1+j]; 34 } 35 anss+=lower_bound(ans.begin(),ans.end(),m-sum+1)-ans.begin(); 36 } 37 cout< endl; 38 } 39 }