題目
思路:因為直接爆蒐會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...