题意 : 每一颗子弹破坏了三个邻近的阳台。(第N个阳台是与第1个相邻)射击后后的生存的怪物都对主角造成伤害- 如此,直到所有的怪物被消灭,求怎样射击才能受到最少伤害。
思路 : 状压,数据不是很大,可以爆一爆,或者DFS下去就行,枚举每一种状态。
1 //1152 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #define oo 1 << 28 6 using namespace std ; 7 8 int a[110],dp[1 << 21] ; 9 bool vis[1 << 21] ; 10 int n ; 11 12 int DFS(int sta,int sum) 13 { 14 if(vis[sta]) return dp[sta] ; 15 vis[sta] = true ; 16 if(sta == 0) return dp[sta] = 0 ; 17 int ans = oo ; 18 for(int i = 0 ; i < n ; i++) 19 { 20 int newsta = sta ,newsum = sum ; 21 for(int j = i-1 ; j <= i+1 ; j++) 22 { 23 int k = j ; 24 if(j == -1) k = n-1 ; 25 else if(j == n) k = 0 ; 26 if(newsta & (1 << k)) 27 { 28 newsta -= (1 << k) ; 29 newsum -= a[k] ; 30 } 31 } 32 if(newsta != sta) 33 ans = min(ans,DFS(newsta,newsum)+newsum) ; 34 } 35 return dp[sta] = ans ; 36 } 37 int main() 38 { 39 while(~scanf("%d",&n)) 40 { 41 int sum = 0 ; 42 memset(a,0,sizeof(a)) ; 43 memset(dp,63,sizeof(dp)) ; 44 memset(vis,false,sizeof(vis)) ; 45 for(int i = 0 ; i < n ; i++) 46 { 47 scanf("%d",&a[i]) ; 48 sum += a[i] ; 49 } 50 dp[(1 << n)-1] = 0 ; 51 printf("%d\n",DFS((1 << n)-1,sum)) ; 52 } 53 return 0 ; 54 }