题意:
n个有能量的原子,每两个原子相碰可以产生能量,之后其中的一个原子会消失。
给出两两相撞的能量表,问只剩一个原子的时候产生的最大的能量是多少。
思路:
由于n的值最大为10,所以考虑压缩状态,就可以进行dp了。
转移方程:dp[i|(1<<k)] = max(dp[i|(1<<k)],dp[i][j] + mp[j][k]),j属于i而k不属于i。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <vector> 5 using namespace std; 6 7 const int N = 15; 8 int mp[N][N]; 9 int dp[1<<N]; 10 11 int main() 12 { 13 int n; 14 while (scanf("%d",&n)!=EOF && n) 15 { 16 memset(dp,0,sizeof(dp)); 17 memset(mp,0,sizeof(mp)); 18 for (int i = 0;i < n;i++) 19 { 20 for(int j = 0;j < n;j++) 21 { 22 scanf("%d",&mp[i][j]); 23 } 24 } 25 for (int i = 1;i < (1 << n);i++) 26 { 27 vector<int> ex,des; 28 for (int j = 0;j < n;j++) 29 { 30 if (i & (1 << j))des.push_back(j); 31 else ex.push_back(j); 32 } 33 for (int j = 0;j < ex.size();j++) 34 { 35 for (int k = 0;k < des.size();k++) 36 { 37 int x = ex[j],y = des[k]; 38 dp[i] = max(dp[i],dp[i^(1<<y)] + mp[x][y]); 39 } 40 } 41 } 42 int ans = 0; 43 for (int i = 0;i < (1<<n);i++) 44 { 45 int cnt = 0; 46 for (int j = 0;j < n;j++) 47 { 48 if (i&(1<<j)) cnt++; 49 } 50 if (cnt == n-1) ans = max(ans,dp[i]); 51 } 52 printf("%d ",ans); 53 } 54 return 0; 55 }