【CF748E】Santa Claus and Tangerines 二分+记忆化搜索

本文解析了一道关于圣诞老人分配橘子的算法题目,通过二分查找和深度优先搜索(DFS)策略,求解在给定条件下每个人分得橘子数目的最小值最大值。文章详细阐述了算法实现过程及优化技巧。

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

题目在这里
题意比较难理解,因为里面有好多我不认识的单词,比如Santa Claus ,比如tangerine

简要大意大概是圣诞老人想要分橘子(圣诞老人为啥要分橘子啊),橘子可以对半分,对半分之后也要对半分,如果橘子瓣是个odd,就要分成odd/2和odd/2+1两部分。然后有k个人,要想每个人都有橘子,求每个人分的橘子数目最小值的最大值。(每个人只能分一次橘子,不可以重复得到)。


首先,这个题目的问法又很二分,我们要求最小值的最大值,显然是二分答案。
具体怎么二分呢,dfs(a[i],x)表示目前这a[i]瓣橘子可以分成最小的是x瓣最多可以分给几个人。
我们的dfs如下,大家应该一看就能理解了:

long long dfs(int v,int x)
{
    if(v<x) return 0;
    if(vis[v]) return vis[v];
    if(v/2<x) return vis[v] = 1;
    if(v&1)
    {
        return vis[v] += dfs(v/2+1,x)+dfs(v/2,x);
    }
    else return vis[v] = 2*dfs(v/2,x);
}

然后鉴于有很多重复操作,我们将它改成记忆化就完事了。

check在这里,很简单吧。(为了降低复杂度,先将a按从大到小排序)。

bool check(int x)
{
    long long ans = 0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
    {
        if(a[i]<x) break;
        ans += dfs(a[i],x);
    }
    return ans>=m;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值