AcWing 171. 送禮物(搜索)

深度優(yōu)先 + 雙向搜索

雙向搜索:將整個需要搜索的對象分成兩半(在已知初態(tài)與終態(tài)的時候可以考慮)

原題鏈接

感悟:首先可能會思考動態(tài)規(guī)劃,但它的時間復雜度是(nv)v太大了,不適合。n比較小,可以考慮爆搜。然后這里有個非常好的技巧,就是把原數(shù)據(jù)分成兩半,在通過一些技巧,剪枝,可以有效的降低時間復雜度。

本題思路

  1. 先搜索前 N / 2 的數(shù)據(jù),枚舉所有可能的重量集合,存入數(shù)組
  2. 對所有重量集合排序,從大到小(順序優(yōu)化),判重(排除冗余)
  3. 在搜索后一半,枚舉所有可能的重量集合,然后當前集合X與前面的數(shù)組中一個集合Y,是得X+Y <= m,且X+Y是最大的
  4. 然后就是到枚舉結束輸出最大的X+Y

剪枝及優(yōu)化

  • 雙向搜索的思路就大大降低了時間復雜度
  • 對于從什么地方開始分開也有講究:前一半的為 2(N/2) 后一半為 2(N/2)*o(二分),所以可以中和下,可在 N/2 + 2 時分開
  • 搜索順序的優(yōu)化: 從大到小
  • 判重: STL 中的unique可以實現(xiàn)數(shù)組中的判重,也可以自己寫一個不難

ACcode

#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;

int n, m, k;
int weights[1 << 24], g[50];
int cnt = 0, ans = 0;

void dfs_1(int u, int sum)
{
    if(u == k)
    {
        weights[cnt++] = sum;
        return;
    }
    
    if((LL)sum + g[u] <= m) dfs_1(u+1, sum+g[u]);
    dfs_1(u+1, sum);
}

void dfs_2(int u, int sum)
{
    if(u == n)
    {
        int l = 0, r = cnt -1;
        while(l < r)
        {
            int mid = l + r + 1 >> 1;
            if(weights[mid] + (LL)sum <= m) l = mid;
            else r = mid - 1;
        }
        if(weights[l] + (LL)sum <= m) ans = max(ans, weights[l] + sum);
        return;
    }
    
    if(g[u] + (LL)sum <= m) dfs_2(u+1, g[u]+sum);
    dfs_2(u+1, sum);
}

int main()
{
    cin >> m >> n;
    for(int i = 0; i < n; i++) cin >> g[i];
    
    sort(g, g+n);
    reverse(g, g+n);
    
    k = n/2 + 2;
    dfs_1(0, 0);
    
    sort(weights, weights+cnt);
    int t = 1;
    for(int i = 1; i < cnt; i++)
        if(weights[i] != weights[i-1])
            weights[t++] = weights[i];
    cnt = t;
    
    dfs_2(k, 0);
    
    cout << ans << endl;
    
    return 0;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 在C語言中,五種基本數(shù)據(jù)類型存儲空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 4,081評論 0 2
  • 對象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法,而不是構造函數(shù)創(chuàng)建對象:僅僅是創(chuàng)建對象的方法,并非Fa...
    孫小磊閱讀 2,186評論 0 3
  • 一年級語文上冊生字表 生字表一(共400字) 啊(ā)愛(ài)安(ān)岸(àn)爸(bà)八(bā)巴(bā)...
    meychang閱讀 3,160評論 0 6
  • 概要 64學時 3.5學分 章節(jié)安排 電子商務網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,880評論 0 3
  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學習記錄文檔,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 3,172評論 2 9

友情鏈接更多精彩內容