[题解](折半搜索)luogu_P4799_BZOJ_4800世界冰球锦标赛

本文探讨了在解决特定类型问题时,如何利用折半搜索和二分查找来优化算法性能,特别是在处理大量数据集时。通过将问题分为两部分并分别求解,再对解进行合并,可以显著提高效率。文章详细介绍了算法实现过程,并提供了一个具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

抄的题解

以及参考:https://www.cnblogs.com/ZAGER/p/9827160.html

2^40爆搜过不了,考虑折半搜索,难点在于合并左右的答案,因为有可能答案同时载左右两边,我们用两个数组记录下来答案,

然后我们再对左边的答案排个序,那么对于右边其中的a来说,它可能产生的集合是与左边<=m-a的状态相结合。使用二分查找

输入要用%lld

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
int n,mid;
ll m,w[50],suma[1<<21],sumb[1<<21],cnta,cntb,ans;
void dfs(int l,int r,ll sum,ll a[],ll &cnt){
    if(sum>m)return;
    if(l>r){
        a[++cnt]=sum;return;
    }
    dfs(l+1,r,sum+w[l],a,cnt);
    dfs(l+1,r,sum,a,cnt);
}
int main(){
    scanf("%d%lld",&n,&m);
    for(int i=1;i<=n;i++)scanf("%lld",&w[i]);
    mid=n/2;
    dfs(1,mid,0,suma,cnta);
    dfs(mid+1,n,0,sumb,cntb);
    sort(suma+1,suma+1+cnta);
    for(int i=1;i<=cntb;i++)
    ans+=upper_bound(suma+1,suma+1+cnta,m-sumb[i])-suma-1;
    printf("%lld\n",ans);
}

 

转载于:https://www.cnblogs.com/superminivan/p/10859329.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值