cf413 D. 2048(dp)
阿新 • • 發佈:2022-03-18
題意:
在一個長度為n的陣列中填2或4,待所有數字全部填好後,按照類似於2048的規則向左合併。給定某些格子上的數,問在當前情況下要使得合併後的最大數不小於 \(2^k\) 有幾種填法。
\(n\le 2000,3\le k\le 11\)
思路:
\(f(i,j)\) 表示考慮到第 \(i\) 個數,和為 \(j\) 的方案數。
因為只能填2或4,所以若一個非嚴格遞減的子段末尾有偶數個2,則整個子段可以合併成一個數;若有奇數個2,則末尾的2不能合併。但是加上這個2不影響能否湊到 \(2^k\)
int n, k, f[N][(1<<11)+3]; signed main() { iofast; cin >> n >> k; f[0][0] = 1; for(int i = 1; i <= n; i++) { int x; cin >> x; for(int j = 0; j <= (1<<k); j++) { //列舉上一個的狀態 if(x != 4) (f[i][min(1<<k,j+2)] += f[i-1][j]) %= mod; if(x != 2) (f[i][j%4==2 ? 4 : min(1<<k,j+4)] += f[i-1][j]) %= mod; } } cout << f[n][1<<k]; }