Recently, researchers on Mars have discovered N powerful atoms. All of them are different. These atoms have some properties. When two of these atoms collide, one of them disappears and a lot of power is produced. Researchers know the way every two atoms perform when collided and the power every two atoms can produce.
You are to write a program to make it most powerful, which means that the sum of power produced during all the collides is maximal.
Input
There are multiple cases. The first line of each case has an integer N (2 <= N <= 10), which means there are N atoms: A1, A2, … , AN. Then N lines follow. There are N integers in each line. The j-th integer on the i-th line is the power produced when Ai and Aj collide with Aj gone. All integers are positive and not larger than 10000.
The last case is followed by a 0 in one line.
There will be no more than 500 cases including no more than 50 large cases that N is 10.
Output
Output the maximal power these N atoms can produce in a line for each case.
Sample Input
2
0 4
1 0
3
0 20 1
12 0 1
1 10 0
0
Sample Output
4
22
题目类型 状态压缩dp,个人感觉是这类型里比较简单的一道,最后也是做出来了,如果假设这些气体都是拍成一列,只有相邻两个才能发生作用,那这题似乎就是区间qp了,一般往往区间的数据量要大一些,接近n^2的复杂度,但是这题是任意的两个气体之间都要考虑,这里用状态压缩,二进制表示,而且也可以看见此类的数控量其实都非常小
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include <iostream>
#include<cmath>
#include <string>
#define mod 9973
#define MAXN 0x1f1f1f1f
using namespace std;
int a[12][12];
int state[1<<10+5];
int n;
int find(int s)
{
if(state[s]!=-1)
return state[s];
int res=0;
for(int i=1;i<=n;i++)
{
if(!(s&(1<<(i-1))))//找到一个为0的位置,
{
int m=0;
for(int j=1;j<=n;j++)//找出一个能使j使a[j][i]最大的值存到m
{
if(s&(1<<(j-1)))
m=max(m,a[j][i]);
}
//printf("m:%d\n",m);
res=max(res,find(s|(1<<(i-1)))+m);到达s这个状态说明之前i这个位置为1,如11—>01,11->10
}
}
return state[s]=res;
}
int main()
{
while(scanf("%d",&n),n)
{
memset(state,-1,sizeof(state));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
state[(1<<n)-1]=0;//dp的边界,如果所有的气体都在如111,那么当然产生的能力为0
int res=0;
for(int i=1;i<=n;i++)
res=max(res,find(1<<(i-1)));//注意了这里传进去的值都必须为001,010,100这些值,就是说只有一个位置上是1,因为到左后只存在一种气体
printf("%d\n",res);
}
return 0;
}