[BZOJ4800][CEOI2015]Ice Hockey World Championship(meet in middle)

题目:

我是超链接
有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());
}

猜你喜欢

转载自blog.csdn.net/blue_cuso4/article/details/80851904