問題G 送禮物 折半dfs 二分)

2021-09-26 05:35:03 字數 1756 閱讀 4745

題目

思路:因為直接爆蒐會t,所以先搜後一半的所有可能的組合,然後排序,搜前一半和組合的權值和加上前一半的組合的權值和(二分搜尋出乙個rec[i],讓其和val的和不大於w的情況),更新ans;

複雜度從o(2n)->o(2n/2 +log(2n/2)*2n/2)=o((1+n/2 *log2) *2n/2)

總複雜度從 前一半複雜度 * 2n/2 變為前一半複雜度 +log2 * 2n/2

#include

#include

#define ll long long

using namespace std;

ll w,n,tot,ans;

ll a[50]

,rec[

1<<22+

1];///rec陣列,記錄後n/2個資料中所有可能的組合的權值和(最多2^22種情況,所以要開這麼大)

void

dfs1

(ll x,ll val)

///dfs後n/2個資料的所有可能的組合的權值和

if(val+a[x]

<=w)

dfs1

(x+1

,val+a[x]);

dfs1

(x+1

,val);}

void

dfs2

(ll x,ll val)

///搜尋前一半的權值和與後一半的組合的權值和最大值

ans=

max(ans,val+rec[l]);

///更新最大值

return;}

if(val+a[x]

<=w)

dfs2

(x+1

,val+a[x]);

dfs2

(x+1

,val);}

intmain()

若要輸出達到w時的組合的方式(牛客多校第九場d)

#include

#include

#include

#define ll long long

using namespace std;

ll w,n,tot,ans;

struct edge

a[50];

struct nodee[1

<<22+

1];bool temp[50]

,t[50];

bool cmp1

(edge a,edge b)

bool cmp2

(node a,node b)

void

dfs1

(ll x,ll val)

///dfs後n/2個資料的所有可能的組合的權值和

if(val+a[x]

.val<=w)

dfs1

(x+1

,val);}

void

dfs2

(ll x,ll val)

///搜尋前一半的權值和與後一半的組合的權值和最大值

ans=

max(ans,val+e[l]

.rec)

;///更新最大值

if(ans==w)

///達到目標最大值,輸出

return;}

if(val+a[x]

.val<=w)

dfs2

(x+1

,val);}

intmain()

送禮物 題解

這道題目是到毒瘤題。首先我們至少去l個,所以我們可以把小於l的用單調佇列直接求出。對取l r個。顯而易見的是左右兩端必分別是這個區間的最小值和最大值。我們可以用01分數規劃。不放令結果最後為ans,則有 a j ans j a i ans i ans k 所以我們就可以愉快地分數規劃啦。includ...

swift送禮物動畫

最近做了乙個用swift寫的送禮動畫,這個動畫本來是在專案中用到的,然後專案改了需求用不上了就想到用swift封裝一下以後如果用得到可以借鑑下。想看下效果圖 思路 1.首先建立乙個動畫的資料model。struct animationmodel iflet giftname dict giftnam...

送禮物 雙向dfs

思路 dfs 先把a陣列排序,由大變小 dfs出前n 2 2 可以湊出的數,放到陣列s中 把s陣列去重排序,行成乙個單調遞增序列 再dfs剩下的數 可以組成的數,每組成乙個,二分找s陣列匹配的最大值 include includeusing namespace std typedef long lo...