Most Powerful ZOJ - 3471

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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值