题解:状压DP,先预处理出一行的情况,可以省很多时间。最后统计的时候,只统计最后一行,因为前几行成功的方案数也被统计到了最后一行。最后注意longlong
代码:
#include <iostream>
#include<cstdio>
#define maxs 2050
using namespace std;
int king[maxs],state[maxs];
int n,need;
long long dp[15][maxs][105];
int cnt=0;
void dfs(int s,int sum,int len){
if(len>=n){
king[++cnt]=sum;
state[cnt]=s;
return ;
}
dfs(s+(1<<len),sum+1,len+2);
dfs(s,sum,len+1);
}
int main()
{
int i,j,k,l;
scanf("%d%d",&n,&need);
dfs(0,0,0);
for(i=1;i<=cnt;i++)dp[1][i][king[i]]=1;
for(i=2;i<=n;i++){
for(j=1;j<=cnt;j++){
for(k=1;k<=cnt;k++){
if(state[k]&state[j])continue;
if((state[k]<<1)&state[j])continue;
if(state[k]&(state[j]<<1))continue;
for(l=need;l>=king[j];l--){
dp[i][j][l]+=dp[i-1][k][l-king[j]];
}
}
}
}
long long ans=0;
for(j=1;j<=cnt;j++)ans+=dp[n][j][need];
cout << ans<< endl;
return 0;
}