Link:
Solution:
思路基本上和 POJ 1185 炮兵阵地 完全相同
都是先对每一行的可能状态进行预处理,只不过一个记录最大值一个记录方案数
不过再一次写的时候还是犯了几个**错误调了一会……
1、对$k$的枚举要从0开始!
$dp$时很多时候为0的状态都有初始值,一定要考虑边界的取舍!
2、位运算的括号问题
一开始$!st[j]\& st[l]$没加括号……
位运算时还是多加一个括号保险吧……
Code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=1025; ll dp[15][MAXN][100],res=0; int n,m,st[MAXN],sum[MAXN],tot=0; int cal(int x) { int ret=0; for(;x;x>>=1) ret+=(x&1); return ret; } int main() { scanf("%d%d",&n,&m); int MAX=(1<<n)-1; for(int i=0;i<=MAX;i++) if(!(i&(i<<1))) st[++tot]=i,sum[tot]=cal(i),dp[1][tot][sum[tot]]=1; for(int i=1;i<n;i++) for(int j=1;j<=tot;j++) for(int k=0;k<=m;k++) if(dp[i][j][k]) for(int l=1;l<=tot;l++) if(!(st[j]&(st[l]<<1)) && !(st[j]&(st[l]>>1)) && !(st[j]&st[l])) dp[i+1][l][k+sum[l]]+=dp[i][j][k]; for(int i=1;i<=tot;i++) res+=dp[n][i][m]; printf("%lld",res); return 0; }