Description
有n个物品,m块钱,给定每个物品的价格,求买物品的方案数。
Input
第一行两个数n,m代表物品数量及钱数
第二行n个数,代表每个物品的价格
n<=40,m<=10^18
Output
一行一个数表示购买的方案数
(想怎么买就怎么买,当然不买也算一种)
Sample Input
5 1000
100 1500 500 500 1000
100 1500 500 500 1000
Sample Output
8
正解:$meet in the middle$。
比较裸的$meet in the middle$,搜索完以后直接把两个栈按照价值排序,用单调指针扫一扫就行了。
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <complex> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cstdio> 8 #include <vector> 9 #include <cmath> 10 #include <queue> 11 #include <stack> 12 #include <map> 13 #include <set> 14 #define inf (1<<30) 15 #define il inline 16 #define RG register 17 #define ll long long 18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 19 20 using namespace std; 21 22 ll st1[2000010],st2[2000010],a[50],n,m,ans,top1,top2; 23 24 il ll gi(){ 25 RG ll x=0,q=1; RG char ch=getchar(); 26 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 27 if (ch=='-') q=-1,ch=getchar(); 28 while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); 29 return q*x; 30 } 31 32 il void dfs1(RG ll x,RG ll cost){ 33 if (x>n/2){ st1[++top1]=cost; return; } 34 dfs1(x+1,cost),dfs1(x+1,cost+a[x]); return; 35 } 36 37 il void dfs2(RG ll x,RG ll cost){ 38 if (x>n){ st2[++top2]=cost; return; } 39 dfs2(x+1,cost),dfs2(x+1,cost+a[x]); return; 40 } 41 42 il void work(){ 43 n=gi(),m=gi(); for (RG ll i=1;i<=n;++i) a[i]=gi(); 44 dfs1(1,0),dfs2(n/2+1,0); 45 sort(st1+1,st1+top1+1),sort(st2+1,st2+top2+1); 46 for (RG ll i=1,j=top2;i<=top1;++i){ 47 while (j && st1[i]+st2[j]>m) j--; ans+=j; 48 } 49 printf("%lld ",ans); return; 50 } 51 52 int main(){ 53 File("championship"); 54 work(); 55 return 0; 56 }