标签:限制 不能 getchar ret ems 位运算 背包 pre name
reference:
https://www.luogu.org/blog/virus2017/1896dnqec
Date:
2019.10.04
*/
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dwn(i,a,b) for(int i=a;i>=b;--i)
template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;}
#define mem(a,b) memset(a,b,sizeof(a))
int f[9+5][512+5][81+5];
//f[i][j][k]表示第i行的状态选的是第j个状态,有k个国王的方案数
//上个状态:f[i-1][jj][k-cnt[j]];
int n,K,tot;
int st[512+5],cnt[512+5];
//st表示当前可行的状态(01串
//cnt表示st[]的状态有多少个1(为了后面利用背包的思想转移)
inline void get_num(int x){
int now=0;
while(x){
x&=(x-1);
now++;
}
cnt[tot]=now;
}
inline void pre_work(){
for(int i=0;i<(1<<n);++i)
if(!(i&(i<<1)))//遇到位运算最好加括号,比如不能写成i&(-i)==0(==优先级比&高)
st[++tot]=i,get_num(i);
}
#undef int
int main(){
#define int long long
#ifdef WIN64
freopen("qinfan.txt","r",stdin);
#endif
rd(n),rd(K);
pre_work();
rep(i,1,tot)f[1][i][cnt[i]]=1;
rep(i,2,n)
rep(j,1,tot)
rep(jj,1,tot){
if(st[j]&st[jj] || (st[j]<<1)&st[jj] || (st[j]>>1)&st[jj])continue;
dwn(k,K,cnt[j])
f[i][j][k]+=f[i-1][jj][k-cnt[j]];
}
int ans=0;
rep(i,1,tot)
ans+=f[n][i][K];
printf("%lld\n",ans);
return 0;
}
标签:限制 不能 getchar ret ems 位运算 背包 pre name
原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11634651.html