18華工校賽 小馬哥的超級鹽水 折半列舉

2022-05-07 03:33:13 字數 1164 閱讀 2030

小馬哥有 \(n\) 杯鹽水,第 \(i\) 杯有 \(a_i\)單位的鹽和 \(b_i\)單位的水。小馬哥很無聊,於是他想知道有多少種這 \(n\) 杯鹽水的非空子集,倒在一起之後鹽和水的比是 \(\frac\),範圍\(2

這道題比賽沒a出來,要是a了就能兩個人分900塊辣

//隔了一天才突然想到,我太菜了

折半列舉過程如下

分兩個桶a,b,分別裝前一半杯子的子集和後一半杯子的子集

先暴力列舉a桶所有組合,裝入乙個排好序的vec,這部分時間複雜度是\(o(2^log_22^)\)

再暴力列舉b桶的方案,二分找出能和a匹配的方案個數,這部分時間複雜度也是\(o(2^log_22^)\)

最後統計a、b自身符合條件的方案就行了

至於如何二分,可以考慮假設a的某個集合本身不能匹配,

設該狀態鹽總和為\(a\),水總和為\(b\),那麼就有\(ay≠bx\)

設b桶列舉的集合中鹽總和為\(c\),水總和為\(d\),那麼有\((a+c)y=(b+d)x\)

簡單移項後得出\(ay-bx=dx-cy\)

按這條式子就能二分了

ps.實現是dalao寫的,自己寫的翻車了,思路沒錯..

#include#include#includeusing namespace std;

const int maxn = 40;

const int maxm = (1<<18)+5;

int elema[maxn],elemb[maxn];

int zka[maxm],zkb[maxm];

void zhangkai(int val,int elem,int size)

for(int i = half+1;i<=n;i++)

zhangkai(zka,elema,half);

zhangkai(zkb,elemb,n-half);

int sizeb = (1<<(n-half));

sort(zkb+1,zkb+sizeb);

long long ans = 0;

int end = 1

return 0;

}

小馬哥的超級鹽水

來呀 題意 給n杯鹽水,每一杯水有a單位鹽,b單位水。給你乙個x和y,問有多少種方法能配成x比y的鹽水。因為n只有35,沒法列舉全部情況,如果n只有一般大,那麼我們可以列舉所有情況。我們可以把n分為兩部分,列舉一部分的所有情況,然後找是否能和另一部分構成解。對於 a1,b1 和 a2,b2 這兩個集...

小馬哥淡定的UBUNTU之旅 軟體安裝

ubuntu下安裝軟體的方法主要有四種 apt dpkg 原始碼 rpm。apt get install softname1 softname2 修復安裝 apt get f install dpkg i package name.deb 針對.tar tar.gz tar.bz2 tar.z ta...

K 小馬哥的超級鹽水 分治 暴力

時間限制 c c 5秒,其他語言10秒 空間限制 c c 131072k,其他語言262144k 64bit io format lld 小馬哥有 輸入第一行包含乙個整數每組資料第一行包含三個整數 接下來每組資料輸出一行,包含乙個整數表示非空子集的個數。示例1 1 5 1 2 1 21 2 1 21...