POJ 1321 棋盘问题(DFS 状压DP)
生活随笔
收集整理的這篇文章主要介紹了
POJ 1321 棋盘问题(DFS 状压DP)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
? ? 用DFS寫當然很簡單了,8!的復雜度,16MS搞定。
? ? 在Discuss里看到有同學用狀態(tài)壓縮DP來寫,就學習了一下,果然很精妙呀。
? ? 狀態(tài)轉(zhuǎn)移分兩種,當前行不加棋子,和加棋子。dp[i][j]中,i代表行數(shù),j代表當前行棋子的狀態(tài)。j的二進制中,1代表有旗子,0代表無棋子。
? ? 貼代碼~狀壓DP果然快一點。
#include <cstdio> #include <cstring>int n,k,count; bool mp[10][10]; int num[256]; int dp[9][256];int main() { // freopen("in.txt","r",stdin);for(int i=1;i<256;i++){int tmp=i;while(tmp){if(tmp&1)num[i]++;tmp>>=1;}}while(~scanf("%d%d",&n,&k) && n!=-1 && k!=-1){char str[20];for(int i=1;i<=n;i++){scanf("%s",str+1);for(int l=1;l<=n;l++){if(str[l]=='#')mp[i][l]=true;elsemp[i][l]=false;}}int status=1<<n;memset(dp,0,sizeof(dp));dp[0][0]=1;for(int i=1;i<=n;i++){for(int j=0;j<status;j++) if(num[j]<=k){dp[i][j]+=dp[i-1][j];for(int l=1;l<=n;l++) if(mp[i][l] && (j&(1<<(l-1)))==0){dp[i][(j|(1<<(l-1)))]+=dp[i-1][j];}}}int ans=0;for(int i=0;i<status;i++) if(num[i]==k)ans+=dp[n][i];printf("%d\n",ans);} }? ? 還有傳統(tǒng)的DFS……
#include <cstdio> #include <cstring>int n,k,count; bool mp[10][10]; bool col[10];void DFS(int x,int rest) {if(rest==0){count++;return;}if(x>n)return;for(int i=1;i<=n;i++) if(!col[i] && mp[x][i]){col[i]=true;DFS(x+1,rest-1);col[i]=false;}if(rest+x<=n)DFS(x+1,rest); }int main() { // freopen("in.txt","r",stdin);while(~scanf("%d%d",&n,&k) && n!=-1 && k!=-1){memset(col,0,sizeof(col));char str[20];for(int i=1;i<=n;i++){scanf("%s",str+1);for(int k=1;k<=n;k++){if(str[k]=='#')mp[i][k]=true;elsemp[i][k]=false;}}count=0;DFS(1,k);printf("%d\n",count);} }?
轉(zhuǎn)載于:https://www.cnblogs.com/IT-BOY/p/3231266.html
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的POJ 1321 棋盘问题(DFS 状压DP)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle 数据库数据排名函数:ran
- 下一篇: c#一个分页控件的例子