SPOJ11469 Subset(折半列舉)

2022-05-07 19:57:16 字數 829 閱讀 5196

給定乙個集合,有多少個非空子集,能劃分成和相等的兩份。$n\leq 20$

看到這個題,首先能想到的是$3n$的暴力列舉,列舉當前元素是放入左邊還是放入右邊或者根本不放,但是顯然是不可取的,看到$n$只有20,考慮折半搜尋,將集合分成兩部分,每個部分$3}$列舉。

接著考慮如何合併,在列舉時計乙個$delta$表示此時左邊和右邊的差值,這樣在右半部分每一次列舉完後我們可以直接在左半部分查詢是否存在乙個$delta$相等,如果相等,則兩個集合的並集滿足條件

#include #include #include typedef long long ll;

template inline void read(t &x)

const int n = 21;

int n, m, a[n], cnt, ans;

std::map ma;

std::vector s[1 << n];

bool ok[1 << n];

void dfs1(int i, int s, int d)

dfs1(i + 1, s, d);

dfs1(i + 1, s | (1 << i), d + a[i]);

dfs1(i + 1, s | (1 << i), d - a[i]);

}void dfs2(int i, int s, int d)

dfs2(i + 1, s, d);

dfs2(i + 1, s | (1 << i), d + a[i]);

dfs2(i + 1, s | (1 << i), d - a[i]);

}int main ()

1146 採藥 詳解

回想起以前似是而非做的題,現在有必要耐下性子,總結一下!要投入熱情了。題意 有m組藥,給出採這個藥的時間time 和 這個藥的價值value。題外意 每個藥只有乙個 問在給分定時間t內如何採藥可以達到最大價值。即求規劃m組藥中的乙個子集,使在t時間內,所取子集的價值和最大。分析 歸類 0 1揹包問題...

1146 快照陣列

題目描述 實現支援下列介面的 快照陣列 snapshotarray snapshotarray int length 初始化乙個與指定長度相等的 類陣列 的資料結構。初始時,每個元素都等於 0。void set index,val 會將指定索引 index 處的元素設定為 val。int snap ...

luogu1146 硬幣翻轉

時空限制 1000ms 128mb 在桌面上有一排硬幣,共n枚,每一枚硬幣均為正面朝上。現在要把所有的硬幣翻轉成反面朝上,規則是每次可翻轉任意n 1枚硬幣 正面向上的被翻轉為反面向上,反之亦然 求乙個最短的操作序列 將每次翻轉n 1枚硬幣成為一次操作 輸入格式 輸入只有一行,包含乙個自然數n n為不...