zoj 3471 Most Powerful

题意:

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 }
原文地址:https://www.cnblogs.com/kickit/p/8834833.html