C++——狀壓DP模板——互不侵犯【四川省選2005】
阿新 • • 發佈:2019-01-30
互不侵犯【四川省選2005】
題目背景
SCOI2005 DAY2 T3
題目描述
在 N×N 的棋盤裡面放 K 個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各一個格子,共 8 個格子。
輸入格式
輸入只有一行,包含兩個數 N,K(1≤N≤9,0≤K≤N*N)。
輸出格式
輸出方案數。
樣例資料 1
輸入 [複製]
3 2
輸出
16
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=10,M=26,P=512; int n,m,t,g[P]; long long ans,f[N][P][M]; int main() { ios::sync_with_stdio(false); cin.tie(NULL); cin>>n>>m; if(m>25||m>=n*n) cout<<"0"<<endl; else { t=1<<n; f[0][0][0]=1; g[0]=0; for(int i=1;i<t;++i) g[i]=g[i>>1]+(i&1); for(int i=1;i<=n;++i) for(int j=0;j<t;++j) if(g[j]<=m&&!(j&j>>1)) for(int k=0;k<t;++k) if(g[k]<=m&&!(k&k>>1)&&!(k&j)&&!(j&k>>1)&&!(j&k<<1)) for(int l=g[j]+g[k];l<=m;++l) f[i][j][l]+=f[i-1][k][l-g[j]]; for(int i=0;i<t;++i) ans+=f[n][i][m]; cout<<ans<<endl; } return 0; }