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 |
比赛的时候怎么就没想到T^T根本就没有往装呀的方向上想啊 orz 其实说起来也不难啊,就是没想到啊
用二进制表示的当前状态,还存在就是1,输了没了就是0;比赛的时候纠结于怎么枚举状态并且表示出来两两比赛输了淘汰、赢了继续比赛的过程,自己写的时候也是写了一个磨磨唧唧的递归,其实远没有那么复杂,dp的过程不是按部就班的非得一一对应的递推,只要有当前状态的转移就好
/************
2016.1.3
nefu1009
840k 58ms C++ (g++ 3.4.3) 948
************/
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,num[14][14],dp[5000];
int main()
{
// freopen("cin.txt","r",stdin);
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&num[i][j]);
memset(dp,0,sizeof(dp));
for(int i=(1<<n)-1;i>=0;i--)
{
for(int j=0;j<n;j++)
{
if(i&(1<<j))
{
for(int k=0;k<n;k++)
{
if(i&(1<<k)) continue;
if(k==j) continue;
dp[i]=max(dp[i],dp[i|(1<<k)]+num[j][k]);
}
}
}
}
int maxn=-1;
for(int i=0;i<n;i++)
{
if(maxn<dp[1<<i]) maxn=dp[1<<i];
}
printf("%d\n",maxn);
}
return 0;
}