/*
状压DP
http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=832
题意:1到n石子顺序排列,1...a...b...n
a合并到b得到金钱mp[a][b],b消失
b合并到a得到金钱mp[b][a],a消失
求最大的金币数
思路:因为最多只有10个石子,可以将每种石子目前的状态压缩成一个
二进制说,假设有个状态是 101 ,那么中间的零,可能是左边的1合并过去的
也可能是右边的1合并过去的,所以要枚举找一个最大值mx
然后mx 加上 dp[111]这个状态的最大值
*/
# include<iostream>
# include<stdio.h>
# include<queue>
# include<string.h>
# define INFI 0x3f3f3f3f
using namespace std;
int mp[15][15],dp[5000];
int main(void)
{
// freopen("in.txt","r",stdin);
int n;
while(cin >> n)
{
memset(mp,0,sizeof(mp));
memset(dp,0,sizeof(dp));
for(int i=0; i<n; ++i)
{
for(int j=0; j<n; ++j)
{
cin >> mp[i][j];
}
}
int ans = 0;
for(int i=(1<<n)-1; i>=1; --i)//n个1 n-1个1 n-2个1....
{
for(int j=0; j<n; ++j)//用来查找0的位置
{
if(!(i&(1<<j)))//枚举寻找0的位置
{
int mx = -INFI;
for(int t=0; t<n; ++t)//用来查找1的位置
{
if(i&(1<<t))//枚举寻找1的位置
{
mx = max(mx,mp[t][j]);//获取最大的一个 [由1位置合并到0位置]位置
}
}
//还没有消去1<<j这个位置的1时候最大值 加上消去这个位置的最大值
dp[i] = max(dp[i],dp[i|(1<<j)]+mx);
}
}
ans = max(ans,dp[i]);
}
cout << ans << endl;
}
return 0;
}
状压DP--NYOJ合并游戏
最新推荐文章于 2019-09-22 23:21:55 发布