小馬哥有 \(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...