题目:
我是超链接
有n个物品,m块钱,给定每个物品的价格,求买物品的方案数。(怎么买或者不买都可以)
n<=40,m<=1e18
题解:
看范围meet in middle
代码:
#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std;
const int M=2000000;
int mb,n,sum1,sum2;
LL tmp1[M],tmp2[M],m,a[50];
void dfs(int t,LL tot,LL *tmp,int &sum)
{
if (tot>m) return;
if (t>mb) {tmp[++sum]=tot;return;}
for (int i=0;i<=1;i++) dfs(t+1,tot+i*(LL)a[t],tmp,sum);
}
LL work()
{
LL ans=0;
sort(tmp1+1,tmp1+sum1+1);
sort(tmp2+1,tmp2+sum2+1);
int l=1,r=sum2;
for (;l<=sum1 && r>=1;l++)
{
while (tmp1[l]+tmp2[r]>m) r--;
int ll=1;
while (l<sum1 && tmp1[l]==tmp1[l+1]) ll++,l++;
ans+=(LL)ll*r;
}
return ans;
}
int main()
{
int num;scanf("%d%lld",&num,&m);
for (int i=1;i<=num;i++)
{
scanf("%lld",&a[++n]);
if (a[n]>m) n--;
}
mb=n/2;
dfs(1,0ll,tmp1,sum1);
mb=n;
dfs(n/2+1,0ll,tmp2,sum2);
printf("%lld",work());
}