[SCOI2005]互不侵犯
状压dp。
code:
#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
int lowbit(int x) {return x&-x;}
int getk(int n)
{
int ans=0;
while(n)
{
++ans;
n-=lowbit(n);
}
return ans;
}
int n,st[1000],tot=0,num[1000];
ll dp[20][1000][100];
void init()
{
int all_state=(1<<n)-1;
for(int i=0;i<=all_state;i++)
{
if(!(i&(i<<1)))
{
st[++tot]=i;
num[tot]=getk(i);
}
}
}
int main()
{
int K;
scanf("%d %d",&n,&K);
init();
//printf("tot:%d\n",tot);
for(int i=1;i<=tot;i++) dp[1][st[i]][num[i]]=1;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=tot;j++)
{
for(int k=1;k<=tot;k++)
{
if(st[j]&st[k]) continue;
if((st[j]<<1)&st[k]) continue;
if(st[j]&(st[k]<<1)) continue;
// puts("kkksc03");
for(int s=1;s<=K;s++) dp[i][st[j]][num[j]+s]+=dp[i-1][st[k]][s];
}
}
}
ll ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=tot;j++)
ans+=dp[i][st[j]][K];
printf("%lld",ans);
return 0;
}