题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3471
题目大意:一排 powerful atoms,任意两个都可以合并,如果i和 j合并后i消失,则 增加 map[j][i]的能量,如果i和 j合并后j消失,则 增加 map[i][j]的能量,问合并之后最后能得到的最大能量值。(即求一个最优的顺序)
解题思路:一维状态压缩水题,定义状态dp[i]为到第i个状态的最大值,则转移方程为:dp[i]=max(dp[i],dp[i|(1<<k)]+map[j][k]);,即第i个状态是由 i|(1<<k)转移而来。
代码如下:
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[1<<11],map[11][11];
int n;
void solve()
{
int num=(1<<n);
for(int i=num-1;i>=0;i--)
{
dp[i]=0;
for(int j=0;j<n;j++)
{
if(i&(1<<j))//找到第j个不为0的位置,和第K个为零的位置合并,且由上个状态转移过来
{
for(int k=0;k<n;k++)
{
if(k==j) continue;
else if(i&(1<<k)) continue;
dp[i]=max(dp[i],dp[i|(1<<k)]+map[j][k]);
}
}
}
}
int Max=-1;
for(int i=0;i<num;i++)
Max=max(Max,dp[i]);
printf("%d\n",Max);
}
int main()
{
while(scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&map[i][j]);
solve();
}
return 0;
}