[BZOJ 1087] 互不侵犯KING
阿新 • • 發佈:2018-07-01
div TP HP col %d HR nbsp zoj ace
Link:
BZOJ 1087 傳送門
Solution:
思路基本上和 POJ 1185 炮兵陣地 完全相同
都是先對每一行的可能狀態進行預處理,只不過一個記錄最大值一個記錄方案數
不過再一次寫的時候還是犯了幾個**錯誤調了一會……
1、對$k$的枚舉要從0開始!
$dp$時很多時候為0的狀態都有初始值,一定要考慮邊界的取舍!
2、位運算的括號問題
一開始$!st[j]\& st[l]$沒加括號……
位運算時還是多加一個括號保險吧……
Code:
#include <bits/stdc++.h> using namespace std; typedef long longll; const int MAXN=1025; ll dp[15][MAXN][100],res=0; int n,m,st[MAXN],sum[MAXN],tot=0; int cal(int x) { int ret=0; for(;x;x>>=1) ret+=(x&1); return ret; } int main() { scanf("%d%d",&n,&m); int MAX=(1<<n)-1; for(int i=0;i<=MAX;i++) if(!(i&(i<<1))) st[++tot]=i,sum[tot]=cal(i),dp[1][tot][sum[tot]]=1; for(int i=1;i<n;i++) for(int j=1;j<=tot;j++) for(int k=0;k<=m;k++) if(dp[i][j][k]) for(int l=1;l<=tot;l++) if(!(st[j]&(st[l]<<1)) && !(st[j]&(st[l]>>1)) && !(st[j]&st[l])) dp[i+1][l][k+sum[l]]+=dp[i][j][k]; for(int i=1;i<=tot;i++) res+=dp[n][i][m]; printf("%lld",res); return 0; }
[BZOJ 1087] 互不侵犯KING