首页 > 其他分享 >折半搜素(meet in the middle)

折半搜素(meet in the middle)

时间:2024-08-26 23:04:39浏览次数:4  
标签:折半 le idx GY long 搜素 meet define

算法介绍

折半搜素通常用来处理数据规模不能直接通过暴力解决,但数据规模又没有特别大的情况。

例如:[P10484 送礼物](P10484 送礼物 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))

题意:作为惩罚,GY 被遣送去帮助某神牛给女生送礼物 (GY:貌似是个好差事)但是在 GY 看到礼物之后,他就不这么认为了。某神牛有 \(N\) 个礼物,且异常沉重,但是 GY 的力气也异常的大 (-_-b),他一次可以搬动重量和在 \(w\) 以下的任意多个物品。GY 希望一次搬掉尽量重的一些物品,请你告诉他在他的力气范围内一次性能搬动的最大重量是多少?

对于所有测试数据,\(1 \le N \le 46\), \(1 \le W,G[i] \le 2^{31}-1\)。

我们可以观察到,如果直接暴力搜素,时间复杂度为 \(O(2^{46})\),这是不可接受的。但是如果拆成两半来搜索,最后将结果合并,时间复杂度为 \(O(n*2^{23})\),这个可以接受的。

代码:

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ios ios::sync_with_stdio(0)
#define endl '\n'
#define pii pair<int, int>
#define debug(x) cout << "x = " << x << endl;
#define lowbit(x) (x & (-x))
using namespace std;
const int N = 50, P = 13331;
int a[1 << 25], w[N], idx, mid, W, n;
ll ans;
void dfs1(int d, ll sum)
{
    if (d > mid)
    {
        a[idx++] = sum;
        return;
    }
    if (sum + w[d] <= W)
        dfs1(d + 1, sum + w[d]);
    dfs1(d + 1, sum);
}
void dfs2(int d, ll sum)
{
    if (d > n)
    {
        int l = -1, r = idx;
        while (l + 1 < r)
        {
            int md = (l + r) / 2;
            if (a[md] + sum <= W)
                l = md;
            else
                r = md;
        }
        ans = max(ans, sum + a[l]);
        return;
    }
    if (sum + w[d] <= W)
        dfs2(d + 1, sum + w[d]);
    dfs2(d + 1, sum);
}
void solve()
{
    int T = 1;
    // cin>>T;
    while (T--)
    {
        cin >> W >> n;
        mid = min(n / 2 + 2,n);
        for (int i = 1; i <= n; i++)
            cin >> w[i];
        sort(w+1,w+1+n,greater<int>());
        dfs1(1, 0);
        sort(a, a + idx);
        idx = unique(a, a + idx) - a;
        dfs2(mid + 1, 0);
        cout << ans << endl;
    }
}
int main()
{
    ios;
    solve();
    return 0;
}

标签:折半,le,idx,GY,long,搜素,meet,define
From: https://www.cnblogs.com/zc-study-xcu/p/18381699

相关文章

  • 跟《经济学人》学英文:2024年08月24日这期 Apple can’t do cars. Meet the Chinese te
    Applecan’tdocars.MeettheChinesetechgiantsthatcanBaidu,HuaweiandXiaomihavebuiltthrivingautobusinesses原文:Ashescreechesaroundcornersatwildlyunsafespeeds,oneofthedesignersoftheJIDURobocar07calmlytalksyourcorrespo......
  • 题解:CF362A Two Semiknights Meet
    题意有两个走法为中国象棋象的棋子,棋盘上有一些坏格子,问它们是否可以在好格子相遇。思路则判断两个棋子是否相遇有两个条件是否可以在一个格子相遇。那个格子是否是好格子。先考虑条件\(1\)设第一个棋子的坐标为\(a_x\)和\(a_y\),第二个棋子的坐标为\(b_x\)和\(b_y......
  • 线性结构查找(顺序、折半、分块)
    对于线性结构的查找,应掌握其查找的过程、构造判定树、分析平均查找长度等。一、顺序查找顺序查找又称线性查找,它对顺序表和链表都是适用的。对于顺序表,可通过数组下标递增来顺序扫描每个元素;对于链表,可通过指针next来依次扫描每个元素。顺序查找通常分为对一般的无......
  • 黑马Java零基础视频教程精华部分_15_基本查找/顺序查找、二分查找/折半查找、插值查找
    系列文章目录文章目录系列文章目录一、基本查找/顺序查找核心思想:从0索引开始挨个往后查找代码:练习:定义一个方法利用基本查找,查询某个元素在数组中的索引,数组包含重复数据。二、二分查找/折半查找核心思想:属于有序查找算法。用给定值先与中间结点比较,每次排除一半的......
  • 搜索之meet in middle(有效的小方法)
    题目:[https://www.luogu.com.cn/problem/P2962](P2962[USACO09NOV]LightsG)算法:meetinmiddle(折半搜索)思路:有\(35\)个点,总共的操作状态有\(2^{35}\)种情况。如果我们采用一般的搜索方式,时间上会毫不犹豫得爆掉。所以,我们要用折半搜索的方式。将所有的点拆分成两个集合,对......
  • PTA 6-13 折半查找
    6-13折半查找(15分)给一个严格递增数列,函数intSearch_Bin(SSTableT,KeyTypek)用来二分地查找k在数列中的位置。函数接口定义:int Search_Bin(SSTableT,KeyTypek)其中T是有序表,k是查找的值。裁判测试程序样例:#include<iostream>usingnamespacestd;#define......
  • Large Language Models meet Collaborative Filtering
    本文是LLM系列文章,针对《LargeLanguageModelsmeetCollaborativeFiltering:AnEfficientAll大型语言模型与协同过滤:一个高效的基于LLM的全方位推荐系统摘要1引言2相关工作3问题定义4提出的方法5实验6结论摘要协同过滤推荐系统(CFRecSys)在增强社......
  • 二分查找法(折半查找)day06
    二分查找(折半查找)前提:查找的序列必须是有序的,否则无法使用二分查找4.二分法查找操作:使用二分法查找有序数组中元素。找到返回索引,不存在输出-1。分析:二分法查找的前提是数组有序。假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量front,mid,end分别指......
  • 折半插入排序算法思想及代码实现
    折半插入排序(BinaryInsertionSort)是插入排序算法的一种优化版本。插入排序的基本思想是将一个记录插入到已经排序好的有序表中,从而得到一个新的、记录数增加1的有序表。传统的插入排序在寻找插入位置时,采用的是顺序比较的方式,即逐个与有序表中的元素进行比较,直到找到比待插入......
  • Apache DolphinScheduler用户线上Meetup火热来袭!
    ApacheDolphinScheduler社区8月用户交流会精彩继续!本次活动邀请到老牌农牧产品实业集团铁骑力士架构工程师,来分享ApacheDolphinScheduler在现代农牧食品加工场景中的应用实践。此外,还将有社区活跃贡献者以ApacheDolphinScheduler为例,总结ApacheDolphinScheduler以及Apache......