浙大月赛的一题,题目的意思是研究人员发现有N个原子两两组合会发生反应产生能量,且其中一个会被和谐掉,给出一个矩阵map,其中map[i][j]表示原子i与j发生反应且原子j被和谐掉所释放的能量,问给定的n个原子反应最多能产生多少能量。
可以用一个二进制表示一个状态,1表示被和谐,那么dp[6] 6-110 表示第1个和第二个原子被和谐,然后用一个数组来存储某个原子被和谐的状态
int cst[11]={1,2,4,8,16,32,64,128,256,512,1024};这个的作用是,如果在某个状态下,第i个原子没被和谐,那么这个状态&cst[i]==0
然后循环所用状态,每次循环找出两个没被和谐的原子j,k,然后+map[j][k];
此题目比较经典,需要以后再慢慢消化吧,直接copy一份代码过来

1 #include <stdio.h>
2 int map[15][15];
3 int cst[11]={1,2,4,8,16,32,64,128,256,512,1024};
4 int dp[1200];
5 int Max(int x,int y)
6 {
7 return x>y?x:y;
8 }
9 int main()
10 {
11 int n,i,j,k,ans;
12 while(1)
13 {
14 scanf("%d",&n);
15 if (n==0) break;
16 for (i=0;i<n;i++)
17 {
18 for (j=0;j<n;j++)
19 {
20 scanf("%d",&map[i][j]);
21 }
22 }
23 for (i=0;i<cst[n];i++)
24 {
25 dp[i]=0;
26 }
27 for (i=0;i<cst[n];i++)//对于每个状态进行拓展
28 {
29 for (j=0;j<n;j++)//枚举每一位,也就是说枚举每个原子将其和谐掉
30 {
31 if ((i & cst[j])!=0) continue;//如果在状态i下该原子已经被和谐了,那么跳过看下一个原子
32 for (k=0;k<n;k++)//否则找一个没有被和谐的原子和谐掉原子j
33 {
34 if ((i & cst[k])==0 && j!=k)//这里有个小陷阱,没有加j!=k会WA,估计是测试数据i=j处的值有的不是0
35 {
36 dp[i|cst[j]]=Max(dp[i|cst[j]],dp[i]+map[k][j]);
37 }
38 }
39 }
40 }
41 ans=0;
42 for (i=0;i<cst[n];i++)
43 {
44 if (dp[i]>ans) ans=dp[i];
45 }
46 printf("%d\n",ans);
47 }
48 return 0;
49 }