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; }
持续更新博客地址:
blog.csdn.net/martinue