题解 CF413D 【2048】
题解地址:
[CF413D]2048 - skylee's Blog
题目大意:
在一个长度为
思路:
动态规划。
定义一个状态为最长不上升后缀的数字和,如
- 当
x=2 时,f[i][\min(j+2,2^k)]+=f[i-1][j] ; - 当
x=4 且当前最后有多余2 时,新加进来的数不可能再和前面的合并了,故不将前面的计入状态,f[i][4]+=f[i-1][j] ; - 当
x=4 且当前最后无多余2 时,f[i][\min(j+4,2^k)]+=f[i-1][j] 。 - 当
x 不确定时,同时进行上述两种转移即可。
时间复杂度
源代码:
#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int K=10,mod=1e9+7;
int f[2][(1<<K)+1];
int main() {
const int n=getint(),k=getint()-1;
for(register int i=f[0][0]=1;i<=n;i++) {
const int x=getint();
std::fill(&f[i&1][0],&f[i&1][1<<k]+1,0);
for(register int j=0;j<=1<<k;j++) {
if(x!=2) (f[i&1][j&1?2:std::min(j+2,1<<k)]+=f[(i&1)^1][j])%=mod;
if(x!=4) (f[i&1][std::min(j+1,1<<k)]+=f[(i&1)^1][j])%=mod;
}
}
printf("%d\n",f[n&1][1<<k]);
return 0;
}