您的位置:首页 > 其它

nefuoj1109-状态压缩dp-游戏争霸赛

2017-07-26 17:46 218 查看
http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109

给定m个人比赛,输了淘汰,赢了继续比,最后有一个人是冠军,给定一个数组,a[i][j]为 i战胜j的欢乐度,问你如何欢乐度最多。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n;
int a[15][15];
int dp[(1<<15)];
/*  dp[i][j]  i为还没有输的人的状态,如果输了,就是0,否则是1
j为当前的冠军。,把j这一维去掉也行,我就去掉了。
我们可以根据状态,不断枚举和当前胜者决战的人。(枚举和当前胜者决战的人时,一定有更多的人还没有输,
这个状态在之前肯定已经记录过了。)
*/
int main()
{   while(~scanf("%d",&n)){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
memset(dp,0,sizeof(dp));
int all=(1<<n)-1;
for(int i=all;i>=0;i--){
for(int v=1;v<=n;v++){
if(i&(1<<(v-1))){
for(int p=1;p<=n;p++){
if(!(i&(1<<(p-1)))&&p!=v){
for(int x=1;x<=n;x++){
dp[i]=max(dp[i],dp[i|1<<(p-1)]+a[v][p]);
}
}
}

}}
}
//这个是描述的  i个人已经输了,

int ans=-1;
for(int i=1;i<=n;i++){

ans=max(ans,dp[1<<(i-1)]);

}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: