【HDU】4539 鄭廠長系列故事——排兵佈陣
阿新 • • 發佈:2018-12-13
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 3527 Accepted Submission(s): 1219
Problem Description 鄭廠長不是正廠長 也不是副廠長 他根本就不是廠長 事實上 他是帶兵打仗的團長 一天,鄭廠長帶著他的軍隊來到了一個n*m的平原準備佈陣。 根據以往的戰鬥經驗,每個士兵可以攻擊到並且只能攻擊到與之曼哈頓距離為2的位置以及士兵本身所在的位置。當然,一個士兵不能站在另外一個士兵所能攻擊到的位置,同時因為地形的原因平原上也不是每一個位置都可以安排士兵。 現在,已知n,m 以及平原陣地的具體地形,請你幫助鄭廠長計算該陣地,最多能安排多少個士兵。 Input 輸入包含多組測試資料; 每組資料的第一行包含2個整數n和m (n <= 100, m <= 10 ),之間用空格隔開; 接下來的n行,每行m個數,表示n*m的矩形陣地,其中1表示該位置可以安排士兵,0表示該地形不允許安排士兵。 Output 請為每組資料計算並輸出最多能安排的士兵數量,每組資料輸出一行。 Sample Input 6 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Sample Output 2 Source Recommend liuyiding |
這個的話,其實和炮兵佈陣是一樣的了,
程式碼:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<vector> using namespace std; int dp[2][200][200] ; int cannot[101] ; int N , M ; int ok(int x){ //同行 if(x & (x<<2)) return 0 ; if(x & (x>>2)) return 0 ; return 1 ; } int Count(int x){ int sum = 0 ; while(x){ if(x&1) sum++ ; x>>=1 ; } return sum ; } void get_all_states(vector<int> &states , vector<int> &people){ int i ; states.clear() ; people.clear() ; for(i = 0 ; i < (1<<M) ; i++){ if(ok(i)){ states.push_back(i) ; people.push_back(Count(i)) ; } } } int DP(){ int i , j , k ,row , sum = 0 ; vector<int> states ; vector<int> people ; get_all_states(states , people) ; memset(dp , -1 , sizeof(dp)) ; for(i = 0 ; i < states.size() ; i++){ if(states[i] & cannot[1]) continue ; dp[1][i][0] = people[i]; } for(row = 2 ; row <= N ; row++){ for(i = 0 ; i < states.size() ; i++){ if(states[i] & cannot[row]) continue ; for(j = 0 ; j < states.size() ; j++){ if(states[j] & cannot[row-1]) continue ; if(states[i] & (states[j]<<1)) continue ; if(states[i] & (states[j]>>1)) continue ; for(k = 0 ; k < states.size() ; k++){ if(states[k] & cannot[row-2]) continue ; if(states[i] & states[k]) continue ; if(states[j] & (states[k]<<1)) continue ; if(states[j] & (states[k]>>1)) continue ; if(dp[(row-1)&1][j][k] == -1) continue ; dp[row&1][i][j] = max(dp[row&1][i][j] , dp[(row-1)&1][j][k] + people[i]) ; } } } } for(i = 0 ; i < states.size() ; i++) for(j = 0 ; j < states.size() ; j++) sum = max(sum , dp[N&1][i][j]) ; return sum ; } int main(){ int i , j , x ; while(cin>>N>>M){ memset(cannot , 0 , sizeof(cannot)) ; for(i = 1 ; i <= N ; i++){ for(j = 0 ; j < M ; j++){ cin>>x ; if(!x) cannot[i] |= (1<<j) ; } } cout<<DP()<<endl ; } return 0 ; }