cf413 D. 2048(dp)
题意:
在一个长度为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];
}

浙公网安备 33010602011771号