NYOJ 832合并游戏(状态压缩dp)

2023-12-06 09:32

本文主要是介绍NYOJ 832合并游戏(状态压缩dp),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

描述
大家都知道Yougth除了热爱编程之外,他还有一个爱好就是喜欢玩。
某天在河边玩耍的时候,他发现了一种神奇的石子,当把两个石子放在一起的时候,后一个石子会消失,而且会蹦出一定数量的金币,这可乐坏了Yougth,但是他想得到最多的金币,他该怎么做?
输入
首先一行,一个n(1<=n<=10),表示有n个石子。
接下来n*n的一个矩阵,Aij表示第i个和第j个合并蹦出的金币值(小于10000,注意合并后j会消失)。
输出
输出最多能得到的金币值。
样例输入
2
0 4
1 0
3
0 20 1
12 0 1
1 10 0
样例输出
4

22

 

这一题典型的状态压缩dp, 直接解释状态压缩方程。这题状态压缩方程不好用式子表示,我大概举个例子讲一下怎么转移的。首先要来一个数来表示目前的一个状态,比如n==8,就是有8个石子,然后接着就是假设有一个状态10101101(十进制173),0表示石子已经没掉了,1表示这个石子还在,那么这个状态其实可以由11101101或者10111101或者10101111这三个状态转化而来,而且就这三个, 而这三个状态相比于10101101这个数多出来的1就是相当于与10101101中的1表示的石子合并时没掉的。这个1应该是变成10101101中的0,所以每找到一个0,就枚举这个状态中所有1,因为与可能是这个1让原来的1没掉了,变成了零。以上举了个例子应该就清楚大概思路了清楚了。

 

AC代码:

 

 

# include <cstdio>
# include <cstring>
# include <algorithm>
# include <vector>
using namespace std;
vector<int> v[20];
int bit[20], a[20][20], dp[15000];
int n;
int cal(int temp){int cnt=0;for(int i=1; i<=n; i++){if(!(temp&1)){cnt++;}temp=(temp>>1);}return cnt;
}
int main(){int i, j, k, temp1, l, ans;bit[1]=1;for(i=2; i<=10; i++){bit[i]=(bit[i-1]<<1);}while(scanf("%d", &n)!=EOF){if(n==1){scanf("%d", &temp1);printf("0\n");continue;}memset(dp, 0, sizeof(dp));dp[(1<<n)-1]=0;for(i=0; i<=10; i++){v[i].clear();}for(i=1; i<=n; i++){for(j=1; j<=n; j++){scanf("%d", &a[i][j]);}}for(i=1; i<=(1<<n)-1; i++){v[cal(i)].push_back(i);}for(i=1; i<=n-1; i++){for(j=0; j<=v[i].size()-1; j++){temp1=v[i][j];for(k=1; k<=n; k++){if(!(temp1&1)){for(l=1; l<=n; l++){if(v[i][j]&bit[l]){dp[v[i][j]]=max(dp[v[i][j]], dp[(v[i][j]|bit[k])]+a[l][k]);}}}temp1=(temp1>>1);}}}ans=0;for(i=0; i<=v[n-1].size()-1; i++){ans=max(ans, dp[v[n-1][i]]);}printf("%d\n", ans);}return 0;
}

 

 

 

 

 

这篇关于NYOJ 832合并游戏(状态压缩dp)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/461343

相关文章

使用Python合并 Excel单元格指定行列或单元格范围

《使用Python合并Excel单元格指定行列或单元格范围》合并Excel单元格是Excel数据处理和表格设计中的一项常用操作,本文将介绍如何通过Python合并Excel中的指定行列或单... 目录python Excel库安装Python合并Excel 中的指定行Python合并Excel 中的指定列P

基于C#实现PDF文件合并工具

《基于C#实现PDF文件合并工具》这篇文章主要为大家详细介绍了如何基于C#实现一个简单的PDF文件合并工具,文中的示例代码简洁易懂,有需要的小伙伴可以跟随小编一起学习一下... 界面主要用于发票PDF文件的合并。经常出差要报销的很有用。代码using System;using System.Col

Python视频剪辑合并操作的实现示例

《Python视频剪辑合并操作的实现示例》很多人在创作视频时都需要进行剪辑,本文主要介绍了Python视频剪辑合并操作的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录介绍安装FFmpegWindowsMACOS安装MoviePy剪切视频合并视频转换视频结论介绍

不删数据还能合并磁盘? 让电脑C盘D盘合并并保留数据的技巧

《不删数据还能合并磁盘?让电脑C盘D盘合并并保留数据的技巧》在Windows操作系统中,合并C盘和D盘是一个相对复杂的任务,尤其是当你不希望删除其中的数据时,幸运的是,有几种方法可以实现这一目标且在... 在电脑生产时,制造商常为C盘分配较小的磁盘空间,以确保软件在运行过程中不会出现磁盘空间不足的问题。但在

在C#中合并和解析相对路径方式

《在C#中合并和解析相对路径方式》Path类提供了几个用于操作文件路径的静态方法,其中包括Combine方法和GetFullPath方法,Combine方法将两个路径合并在一起,但不会解析包含相对元素... 目录C#合并和解析相对路径System.IO.Path类幸运的是总结C#合并和解析相对路径对于 C

Qt实现文件的压缩和解压缩操作

《Qt实现文件的压缩和解压缩操作》这篇文章主要为大家详细介绍了如何使用Qt库中的QZipReader和QZipWriter实现文件的压缩和解压缩功能,文中的示例代码简洁易懂,需要的可以参考一下... 目录一、实现方式二、具体步骤1、在.pro文件中添加模块gui-private2、通过QObject方式创建

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

hdu1565(状态压缩)

本人第一道ac的状态压缩dp,这题的数据非常水,很容易过 题意:在n*n的矩阵中选数字使得不存在任意两个数字相邻,求最大值 解题思路: 一、因为在1<<20中有很多状态是无效的,所以第一步是选择有效状态,存到cnt[]数组中 二、dp[i][j]表示到第i行的状态cnt[j]所能得到的最大值,状态转移方程dp[i][j] = max(dp[i][j],dp[i-1][k]) ,其中k满足c

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que