表示裸状压DP
f[i][j][k]
j表示第i行的国王位置,k表示i行和i行前共有k个国王
f[i][j][k+num[j]]=∑f[i−1][o][k]
}
ans=∑2n−1i=0f[n][i][m]
Then,AC
#1
AC
0ms/13839kB
#2
AC
0ms/13839kB
#3
AC
0ms/13839kB
#4
AC
0ms/13839kB
#5
AC
1ms/13839kB
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<queue>
#include<time.h>
#include<fstream>
#include<string>
#include<set>
#include<list>
#include<stdlib.h>
#define fr(i,a,b) for(int i=a,_end_=b;i<=_end_;i++)
#define fd(i,a,b) for(int i=a,_end_=b;i>=_end_;i--)
#define frei(s) freopen(s,"r",stdin)
#define freo(s) freopen(s,"w",stdout)
#define ll long long
#define uns unsigned
using namespace std;
#define rt return
#define gc getchar()
#define ln putchar('\n')
ll lowbit(ll x)
{
rt x&(-x);
}
int read(){
int s=0,k=1;
char c=getchar();
while((c<'0'||c>'9')&&c!='-')c=gc;
if(c=='-'){
k=-1;
c=gc;
}
while(c>=48&&c<='9'){
s=s*10+c-48;
c=gc;
}
rt s*k;
}
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-a/b*y;
return d;
}
double log(double x,double y)
{
rt log10(x)/log10(y);
}
ll gcd(ll x,ll y)
{
rt y?gcd(y,x%y):x;
}
ll P(ll x,ll y)//x>=y
{
ll r=1;
fr(i,1,y)
r*=(x-i+1);
rt r;
}
ll P(ll x,ll y,ll modnum)//x>=y
{
ll r=1;
fr(i,1,y)
r=r*(x-i+1)%modnum;
rt r;
}
int n,m,ans,num[1<<9],f[10][1<<9][100];
int main(){
#ifndef ONLINE_JUDGE
freopen("","r",stdin);
freopen("","w",stdout);
#endif
n=read();
m=read();
fr(i,1,(1<<n)-1)
num[i]=1+num[i-(i&(-i))];//计算有几个国王
f[0][0][0]=1;//边界
fr(i,1,n)
fr(j,0,(1<<n)-1)
if(!((j&(j<<1))|(j&(j>>1))))//判断可不可以这样放
fr(o,0,(1<<n)-1)
if(!((j&(o<<1))|(j&(o>>1))|(j&o)))//判断是否冲突
fr(k,0,m)
f[i][j][k+num[j]]+=f[i-1][o][k];
fr(i,0,(1<<n)-1)
ans+=f[n][i][m];//累加每一个情况
printf("%d\n",ans);
rt 0;
}