BZOJ 1087 互不侵犯king

來源:互聯網
上載者:User

標籤:

       這道題與皇后問題極像,只是兩者的攻擊範圍不一樣,同時根據題目限制可以發現,這道題資料的特殊性,棋盤很小,因此想到用狀態壓縮DP的方法求解。

       首先將每一行互不侵犯的可能列出來,用1、0的方式記錄,之後根據要求會發現,每一行的情況受上一行的情況限制,於是從第一行進行一層層的判斷。又由於國王的攻擊是一個九宮格,因此痛點在於兩國王處於對角,則進行判斷時將下一行向左移一位或向右移一位再進行判斷。最後記得國王數是一定的,用一個變數記錄一下。

       程式無太大的突出,但每一步寫的較清晰,希望對大家有所協助。

#include<cstdlib>#include<cstdio>#include<iostream>#include<cmath>#include<cstring>#define MAXN 100 //對MAXN進行賦值 。 using namespace std;long long int f[MAXN]/*行數*/[MAXN]/*狀態*/[600]/*當前國王總數*/,i_total/*最終結果*/; int stay[MAXN],cnt[MAXN]; // stay用於記錄每種狀態壓縮後的值。 cnt用於記錄對應的狀態中的1的個數。int map[MAXN]/*i*/[MAXN]/*j*/; // 當上一狀態為 i,下一狀態為 j時,是否合法。 int i_side,i_number,i_temp=0; //邊長、數量、每種狀態的個數。 void pre_dfs(int x,int y,int z) //預先處理:x 是放了幾顆國王,y 是當前放的位置,z 是目前狀態壓縮後的值。 {    stay[++i_temp]=z; //在stay數組中進行儲存,記錄目前的狀壓值。     cnt[i_temp]=x; // 在cnt數組中進行儲存,記錄已放國王的數目     if(x>=(i_side+1)/2||x>=i_number)  //如果x超範圍限制,則返回停止。     {        return;    }      for(int i=y+2;i<=i_side;i++) //用for迴圈重複所有可能,將每一種可能用遞迴進行記錄。     {        pre_dfs(x+1,i,z+(1<<(i-1)));    }         }void pre_map(){     for(int i=1;i<=i_temp;i++)    {         for(int j=1;j<=i_temp;j++)         {            map[i][j]=map[j][i]=((stay[i]&stay[j])||((stay[i]>>1)&stay[j])||((stay[i]<<1)&stay[j]))?0:1;//對 map[i][j]、 map[j][i]進行賦值,如果不移動衝突或左移衝突或右移衝突,則賦值為0,反之為1。         }    }              for(int i=1;i<=i_temp;i++)    {          f[1][cnt[i]][i]=1; //用f數組記錄處於第一行、cnt[i]的狀態下、有 i個國王時的情況。     }      }int main(){    scanf("%d%d",&i_side,&i_number);//輸入邊長及王的個數         pre_dfs(0,-1,0); //傳入初始值進行深搜。     pre_map(); // 預先處理一下每種狀態。         for(int i=2;i<=i_side;i++)    {          for(int j=0;j<=i_number;j++) //國王必須能全部放下。          {    for(int q=1;q<=i_temp;q++) //枚舉上一行狀態。                 {                       if(cnt[q]>j)//狀態國王數量要小於等於前 i行國王數量 j。                        {                               continue;                        }                          for(int i_number=1;i_number<=i_temp;i_number++                       {                  if(map[i_number][q]&&cnt[i_number]+cnt[q]<=j)                  {                                        f[i][j][q]+=f[i-1][j-cnt[q]][i_number];                        }                        }                        }          }       }             for(int i=1;i<=i_temp;i++) //計算最終值。     {        i_total=i_total+f[i_side][i_number][i];    }             printf("%lld\n",i_total); //輸出結果。         return 0;}

BZOJ 1087 互不侵犯king

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.