資料範圍很狀壓。
設 \(f_\) 表示 \(sta\) 為已放訊號站集合時最小的代價。
若能求出 $g_i(sta) $ 表示在 \(sta\) 的狀態下放 \(i\) 的代價的係數(即其放的位置的係數),那麼我們就可以在 \(o(m\times2^m)\) 的複雜度內使用 dp 解決問題。
注意到 \(g_i(sta)\) 可以在 \(o(m^2\times 2^m)\) 的複雜度內輕易求出。
設 \(l_i(j)\) 表示滿足 \(s_i=i\) 且 \(s_=j\) 的個數,\(r_i(j)\) 表示 \(s_i=i\) 且 \(s_=j\) 的個數。
列舉 \(i,sta\) 以及 \(j,k\),那麼有:
\[g_i(sta)=\sum_j+\sum_k
\]其中 \(j\in sta,k\not\in sta\)。
瓶頸在於求解 \(g\) 陣列。
注意到 \(g\) 陣列是可以遞推的。
\[g_i(sta\cup\)=g_i(sta)+l_i(x)\times(1-k)+r_i(x)\times(1+k)
\]這樣我們在 \(o(m\times2^m)\) 的時間內處理出來了 \(g\) 陣列,但是我們會爆空間,得優化空間。
我們考慮乙個結論:
二進位制從 \(0\) 數到 \(n\),所有位元位變化的總次數為 \(2n\)。證明:第 \(0\) 位每增加 \(1\) 變一次,第 \(1\) 位每增加 \(2\) 變一次,以此類推,第 \(i\) 位每增加 \(2^i\) 變一次。
那麼總變化次數就是:
\[n\sum_i\dfrac=2n
\]所以我們可以將 \(g\) 陣列 \(sta\) 那維滾掉,在 dp 的時候隨著 sta 的增加暴力更新 \(g_i\) 即可。
總複雜度 \(o(m\times2^m)\)。
**如下:
#include#define lowbit(i) (i&(-i))
using namespace std;
const int maxn = 1e5+5;
bool small;
int n,m,k,s[maxn],f[1<<23],g[23],c[23][23],l[23][23],r[23][23];
int lg[(1<<23)];
bool sunny;
int main()
memset(f,0x3f,sizeof f);f[0]=0;
for(int i=0;ig[i]+=l[i][j]*k-r[i][j],c[i][j]+=l[i][j]*(1-k)+r[i][j]*(1+k);
for(int sta=0;sta<(1
}
省選聯考 2020 A B 卷 訊號傳遞
推薦閱讀 參考資料 對於乙個傳遞 x y,x y 表示座標,代價是 beginy x,quad xy end 即所有的的代價都可以換成乙個點的座標的倍數,於是設 g s,i 表示點 i 前面的集合為 s 時,其對整體代價的貢獻。然後就可以乙個乙個放了 f s g i,s f s 但是 g 陣列要卡空...
聯合省選 2020A 組合數問題 題解
這題算是我斯特林數的入門題,順便安利大佬的部落格,我是從這篇部落格中學的斯特林數。begin sum n f k times x k times dbinom n k sum n m right x k dbinom nk texttt sum n m ii j endk right x k dbi...
2020 聯合省選 雜題選講(基本都不會)
b卷 d1t1 隨便口胡了乙個貪心就a了。題目意思不難理解,這題目直接就能想到貪心求解,然後隨便口胡了乙個演算法 比如說我們現在手裡拿到的牌的數是x xx,位置為p pp,則我們要求最小的r rr,滿足x k p 1rak x sum ra k x k p 1r ak 大概的口胡證明如下 假設我們現...