nefu1109(状态压缩dp)

Description

2015年英雄联盟校园争霸赛决赛于北京时间7月31日在东北林业大学体育馆举行。经过初选的洗礼后,有来自全国各地的n支队伍汇集到本次总决赛,比赛最终要角逐出一名冠军。规则是:队伍两两之间进行比赛,失败者被淘汰,胜利者晋级,获得和其他队伍进行较量的资格,并且为本场比赛贡献一定的精彩度。比如:i和j比赛,j被淘汰,那么比赛增加a[i,j]的精彩度。作为这场比赛的赞助商东东在思考一个问题,比赛的最终精彩度怎样,到底是不是要投资呢?那么就请你帮东东预算一下比赛可能出现的最高精彩度是什么?

Input

输入数据有多组。每组第一行包含一个整数n(2<=n<=10)代表参加比赛的总队伍数。接下来是一个n行n列的矩阵,a[i,j]代表i和j比赛并且j被淘汰产生的精彩度(a[i,j]<=10000)

Output

输出包含一个整数,表示比赛可能出现的最大的精彩度。

Sample Input

2
0 4
1 0
3
0 20 1
12 0 1
1 10 0

Sample Output

4
22

题意中文不多说,不过这题刚开始想复杂悲剧TLE了。。不过马上又有了优化思路就过了。

思路:由于数据给的太小,所以我们只要考虑怎么去记录这个最大精彩程度就ok,这题总共只有一个要考虑的就是所有人的状态,只有这一个状态要考虑,所以我们理所当然的要想到用dp[i]来表示状态就ok。

状态转移的过程:用0表示某个人没被淘汰,1表示被淘汰了,这样状态转移就成了dp[i|(1<<j)]=max(dp[i]+max0);其中max0表示j这个人被淘汰的时候能用最大精彩程度淘汰他的最大精彩程度。然后就没什么的了。。


#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
using namespace std;
typedef long long ll;
int dp[1<<10];
int n;
int tu[15][15];
int main()
{
    while(~scanf("%d",&n))   
    {
        memset(dp,-1,sizeof(dp));
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                scanf("%d",&tu[i][j]);
        dp[0]=0;
        for(int i=0; i<(1<<n); i++)
            for(int j=0; j<n; j++)
                if(!((1<<j)&i))
                {
                    int max0=0;
                    for(int k=0; k<n; k++)
                        if(!((1<<k)&i)&&k!=j)
                            max0=max(max0,tu[k][j]);
                    dp[(1<<j)|i]=max(dp[(1<<j)|i],dp[i]+max0);
                }
        printf("%d\n",dp[(1<<n)-1]);
    }
    return 0;
}




posted @ 2016-04-28 18:21  martinue  阅读(133)  评论(0编辑  收藏  举报