Zoj 3471 Most Powerful 状态压缩

来源:互联网 发布:淘宝极速退款条件 编辑:程序博客网 时间:2024/06/11 11:23

题目链接: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;}


0 0
原创粉丝点击