日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu 4529(状态dp)

發布時間:2025/3/16 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu 4529(状态dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鄭廠長系列故事——N騎士問題

Time Limit: 6000/3000 MS (Java/Others)????Memory Limit: 65535/32768 K (Java/Others)


Problem Description 鄭廠長不是正廠長
  也不是副廠長
  他根本就不是廠長
  還是那個騰訊公司的碼農
  一個業余時間喜歡下棋的碼農
  
  最近,鄭廠長對八皇后問題很感興趣,拿著國際象棋研究了好幾天,終于研究透了。興奮之余,坐在棋盤前的他又開始無聊了。無意間,他看見眼前的棋盤上只擺了八個皇后,感覺空蕩蕩的,恰好又發現身邊還有幾個騎士,于是,他想把這些騎士也擺到棋盤上去,當然棋盤上的一個位置只能放一個棋子。因為受八皇后問題的影響,他希望自己把這些騎士擺上去之后,也要滿足每2個騎士之間不能相互攻擊。
  現在鄭廠長想知道共有多少種擺法,你能幫助他嗎?

騎士的下法:
  每步棋先橫走或直走一格,然后再往外斜走一格;或者先斜走一格,最后再往外橫走或豎走一格(即走“日”字)。可以越子,沒有"中國象棋"的"蹩馬腿"限制。

Input 輸入第一行為一個整數T(1<=T<=8),表示有T組測試數據;
每組數據首先是一個整數N(1<=n<=10),表示要擺N個騎士上去;
接下來是一個8*8的矩陣來描述一個棋盤,’.’表示這個位置是空的,’*’表示這個位置上已經放了皇后了;
數據中的初始棋盤保證是一個合法的八皇后擺法。

Output 對每組數據,請在一行內輸出一個整數,表示合法的方案數。

Sample Input 2 1 *....... ....*... .......* .....*.. ..*..... ......*. .*...... ...*.... 2 *....... ....*... .......* .....*.. ..*..... ......*. .*...... ...*....
Sample Output 56 1409
Source 2013騰訊編程馬拉松初賽第五場(3月25日)?

解題思路:定義狀態dp[i][j][p][q]:表示前i行,使用了j個騎士,第i行的狀態為p,第i-1行的狀態為q的方案數。這是我最開始的想法,但是后來一想時間復雜度會超大,所以就一直不敢去寫,結果看了別人的解題報告,確實是這么思考的,但很詫異居然沒有超時。
AC: #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int t,N; char s[10][10]; bool suit[10][1<<8+5]; int dp[8][11][1<<8][1<<8];//dp[i][j][a][b],第i行,前i行j個騎士,i行狀態a,i-1行狀態b的方案數 int one[1<<8+5]; //處理出每行合法的狀態 inline void init() {memset(suit,0,sizeof(suit));for(int i=0;i<8;i++){for(int j=0;j< 1<<8;j++){int tag=1;for(int k=0;k<8;k++){if(s[i][k]=='*'&&(j&(1<<k))){tag=0; break;}}if(tag) suit[i][j]=1;}} } inline int getOne(int i) {int ans=0;while(i){ans+=i%2;i/=2;}return ans; }int main() {for(int i=0;i<(1<<8);i++)one[i]=getOne(i);scanf("%d",&t);while(t--){scanf("%d",&N);for(int i=0;i<8;i++) scanf("%s",s[i]);init();memset(dp,0,sizeof(dp));for(int i=0;i<(1<<8);i++){if(suit[0][i] && one[i]<=N){dp[0][one[i]][i][0]=1;}}for(int i=1;i<8;i++)for(int n=0;n<=N;n++)for(int j=0;j<(1<<8);j++){if(one[j] > n) continue;if(!suit[i][j]) continue;for(int k=0;k< 1<<8;k++){if(k & (j<<2)) continue;if(k & (j>>2)) continue;for(int r = 0;r < (1<<8);r++){if(r & (j<<1)) continue;if(r & (j>>1)) continue;dp[i][n][j][k]+=dp[i-1][n-one[j]][k][r];}}}int ans=0;for(int i=0;i<(1<<8);i++){if(suit[7][i]){for(int j=0;j<(1<<8);j++){if(suit[6][j])ans+=dp[7][N][i][j];}}}printf("%d\n",ans);} }

總結

以上是生活随笔為你收集整理的hdu 4529(状态dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。