nyoj 832

     这是一道集合上的动态规划,和最优配对问题很相似,不同的是:最优配对问题的思想是配对后两个元素都消失,而合并游戏的思想是合理配对后只消失一个元素。那么合并到最后的时候肯定会有一个石子留下,但是并不确定会是哪个石子留下,所以需要对石子进行逐个枚举。

    用数组d[S]来表示S集合中所能得到的最多硬币数目,用数组a[j][i]来表示石子j和i合并后所得的金币数目(合并后消失的是i),对第i个石子逐个进行枚举,即就是,假设第i个石子先消失,那么状态转移方程便是:d[S]=max(d[S],a[j][i]+d[S-{i}]).

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
#define Max 11
using namespace std;
int n,a[Max][Max],S,dp[1<<Max];
int main()
{
    int i,j;
    while(scanf("%d",&n)!=EOF)
    {
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            scanf("%d",&a[i][j]);
    for(S=0;S<(1<<n);S++)
    {
      dp[S]=0;
      for(i=0;i<n;i++)//对集合S中的元素逐个进行枚举 
        if(S&(1<<i)){
            //printf("i=%d\n",i);
            for(j=0;j<n;j++)
                if(i!=j&&(S&(1<<j))){
                    //printf("j=%d\n",j);
                    dp[S]=max(dp[S],a[j][i]+dp[S^(1<<i)]);}
                }
     //printf("%d %d\n",S,dp[S]);
    }
    //printf("\n\n");
    printf("%d\n",dp[(1<<n)-1]); 
 }        
    system("pause");
    return 0;
} 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值