【洛谷P1896】互不侵犯
阿新 • • 發佈:2019-03-19
and += 題目 space clu parse amp 之間 位置
題目大意:給定 N*N 的棋盤,一共放 K 個國王,一共有多少種方法。
題解:
i&i<<1
判斷是否每個 1 的位置之間都有 0。i&j<<1
判斷 i 中為 1 的位置與 j 中為 1 的位置是否存在右下角的影響。
相比於鋪磚問題,此題僅僅多了一個必須要放 k 個國王,那在此基礎上加一個維度,表示放了多少個國王即可。
代碼如下
#include <bits/stdc++.h> using namespace std; int n,m,cnt[1<<9]; long long f[10][1<<9][100]; bool ins[1<<9]; void read_and_parse(){ scanf("%d%d",&n,&m); for(int i=0;i<1<<n;i++)if(!(i&i<<1)){ ins[i]=1; int res=0; for(int j=0;j<n;j++)if(i>>j&1)++res; cnt[i]=res; } } void solve(){ f[0][0][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<1<<n;j++)if(ins[j]) for(int k=0;k<1<<n;k++)if(ins[k]&&(j&k)==0&&(j&k<<1)==0&&(j&k>>1)==0) for(int w=m;w>=cnt[j];w--) f[i][j][w]+=f[i-1][k][w-cnt[j]]; long long ans=0; for(int i=0;i<1<<n;i++)if(ins[i])ans+=f[n][i][m]; printf("%lld\n",ans); } int main(){ read_and_parse(); solve(); return 0; }
【洛谷P1896】互不侵犯