Description
有n个物品,m块钱,给定每个物品的价格,求买物品的方案数。
n<=40,m<=10^18
(想怎么买就怎么买,当然不买也算一种)
Solution
其实我一开始不是很懂题意。。感觉这类的题目做一次就够了吧?
显然可行的暴力是dfs,时间复杂度不能承受就分成两半暴力然后二分查找
注意开LL的问题(只有我没开LL吧?
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long LL;
const int N=55;
LL a[N],v[N],m,ans;
int n;
void dfs1(int dep,LL sum) {
if (sum>m) return ;
if (dep==n/2+1) {
v[++v[0]]=sum;
return ;
}
dfs1(dep+1,sum+a[dep]);
dfs1(dep+1,sum);
}
int find(LL x) {
int ret;
int l=1,r=v[0];
while (l<=r) {
int mid=(l+r)>>1;
if (v[mid]<=x) ret=mid,l=mid+1;
else r=mid-1;
}
return ret;
}
void dfs2(int dep,LL sum) {
if (sum>m) return ;
if (dep==n+1) {
if (m-sum<v[1]) return ;
ans+=find(m-sum);
return ;
}
dfs2(dep+1,sum+a[dep]);
dfs2(dep+1,sum);
}
int main(void) {
scanf("%d%lld",&n,&m);
rep(i,1,n) scanf("%lld",&a[i]);
dfs1(1,0);
std:: sort(v+1,v+v[0]+1);
dfs2(n/2+1,0);
printf("%lld\n", ans);
return 0;
}