zoj3802:easy 2048 again(状压dp)
zoj月赛的题目,非常不错的一个状压dp。。
题目大意是一个一维的2048游戏
只要有相邻的相同就会合并,合并之后会有奖励分数,总共n个,每个都可以取或者不取
问最终得到的最大值
数据范围n<=500 , a[i]={2,4,8,16};
分析:
首先明确一下自动合并的意思,比如原有 8,4,2,进入一个2 就会变成16
所以我们需要记录前面的所有数字。。计算了一下发现最大情况,500个16会合成4096 =2^12
显然全部记录是不可能的。那么怎么处理呢
我们发现,只有递减的序列才有可能向前合并。。所以我们只需要记录某个状态末尾的递减序列即可
最大数只有2^12,所以递减序列个数只有2^13-1种,可以记录了。。
之后就是状态转移的问题了。
不取当前数状态不变
取当前数分三种情况
1.前面有比当前数更小的,则如果取这个数,递减序列将只有这一个数
2.前面的末尾恰好跟当前数相等,那么向上合并直至不能合并为止
3.前面的末尾比当前数大,那么直接将当前数插入状态中
具体实现看代码,用了一点位运算挺有意思的
- #include <iostream>
- #include <stdio.h>
- #include<string.h>
- #include<algorithm>
- #include<string>
- #include<ctype.h>
- using namespace std;
- #define MAXN 10000
- int dp[][];
- int a[];
- int main()
- {
- #ifndef ONLINE_JUDGE
- //freopen("in.txt","r",stdin);
- #endif
- int T,n;
- scanf("%d",&T);
- while(T--)
- {
- scanf("%d",&n);
- for(int i=;i<=n;i++)
- {
- scanf("%d",a+i);
- }
- memset(dp,-,sizeof(dp));
- dp[][]=;
- dp[][a[]]=a[];
- for(int i=;i<=n;i++)
- {
- for(int j=;j<=;j++)
- {
- if(dp[(i-)%][j]==-)
- {
- continue;
- }
- dp[i%][j]=max(dp[i%][j],dp[(i-)%][j]); //不取
- if(j&(a[i]-))
- {
- dp[i%][a[i]]=max(dp[i%][a[i]],dp[(i-)%][j]+a[i]); //情况1
- continue;
- }
- int state,score;
- if(j&a[i])
- {
- int tmp=j/a[i],k=;
- score=a[i];
- while(tmp%)
- {
- k++;
- tmp/=;
- score+=a[i]<<k;
- }
- state=((tmp<<k)*a[i])|(a[i]<<k);
- dp[i%][state]=max(dp[i%][state],dp[(i-)%][j]+score); //情况2
- continue;
- }
- state=j|a[i];
- score=a[i];
- dp[i%][state]=max(dp[i%][state],dp[(i-)%][j]+score); //情况3
- }
- }
- int ans=-;
- for(int i=;i<;i++)
- {
- ans=max(ans,dp[n%][i]);
- }
- printf("%d\n",ans);
- }
- return ;
- }
zoj3802:easy 2048 again(状压dp)的更多相关文章
- Codeforces Round #568 (Div. 2) G1. Playlist for Polycarp (easy version) (状压dp)
题目:http://codeforces.com/contest/1185/problem/G1 题意:给你n给选项,每个选项有个类型和价值,让你选择一个序列,价值和为m,要求连续的不能有两个相同的类 ...
- ZOJ3802 Easy 2048 Again (状压DP)
ZOJ Monthly, August 2014 E题 ZOJ月赛 2014年8月 E题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?proble ...
- 刷题向》关于第一篇状压DP BZOJ1087 (EASY+)
这是本蒟蒻做的第一篇状压DP,有纪念意义. 这道题题目对状压DP十分友善,算是一道模板题. 分析题目,我们发现可以用0和1代表每一个格子的国王情况, 题目所说国王不能相邻放置,那么首先对于每一行是否合 ...
- Codeforces 544E Remembering Strings 状压dp
题目链接 题意: 给定n个长度均为m的字符串 以下n行给出字符串 以下n*m的矩阵表示把相应的字母改动成其它字母的花费. 问: 对于一个字符串,若它是easy to remembering 当 它存在 ...
- 多米诺骨牌放置问题(状压DP)
例题: 最近小A遇到了一个很有趣的问题: 现在有一个\(n\times m\)规格的桌面,我们希望用\(1 \times 2\)规格的多米诺骨牌将其覆盖. 例如,对于一个\(10 \times 11\ ...
- hdu 3247 AC自动+状压dp+bfs处理
Resource Archiver Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Ot ...
- POJ 2411 Mondriaan's Dream -- 状压DP
题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...
- 状态压缩动态规划 状压DP
总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...
- TZOJ 2289 Help Bob(状压DP)
描述 Bob loves Pizza but is always out of money. One day he reads in the newspapers that his favorite ...
随机推荐
- 浅谈zygote服务中的设计思路
zygote服务是Android启动和服务APK的核心服务,每个APK都是通过zygote启动,今日阅读它的源码学习到一个不错的设计思路. 首先看看一个APK通过zygote的启动流程: 按照一般的设 ...
- JS(三)
1.检查用户名中是否含有特殊字符: <!DOCTYPE html> <html lang="en"> <head> <meta chars ...
- windows服务程序
首先创建一个myService的窗体程序作为服务安装卸载控制器(管理员身份运行vs,windows服务的安装卸载需要管理员权限) 在同一个解决方案里面添加一个windows服务程序,取名myWin ...
- [转]ANDROID仿IOS微信滑动删除_SWIPELISTVIEW左滑删除例子
转载:http://dwtedx.sinaapp.com/itshare_290.html 本例子实现了滑动删除ListView的Itemdemo的效果.大家都知道.这种创意是来源于IOS的.左滑删除 ...
- Zend Studio使用
也许你能够用Dreamweaver.Notepad++或者Editplus这种东西完毕你的系统,但所谓“工欲善其事,必先利其器”,偶觉得 一个给力的IDE对于新手还是非常必要的,而Zend作为PHPe ...
- mysql报错"ERROR 1206 (HY000): The total number of locks exceeds the lock table size"的解决方法
1. 问题背景 InnoDB是新版MySQL(v5.5及以后)默认的存储引擎,之前版本的默认引擎为MyISAM,因此,低于5.5版本的mysql配置文件.my.cnf中,关于InnoD ...
- 在VMware中为Linux系统安装VM-Tools的详解教程
在安装Linux的虚拟机中,单击“虚拟机”菜单下的“安装Vmware-Tools”. 先介绍一下下面安装该工具时要用到的几个目录: /mnt 挂载目录,用来临时挂载别的文件系统,硬件设备 /tmp临时 ...
- Java 图片切圆角,消除锯齿
public static BufferedImage setBorderRadius(BufferedImage srcImage, int radius){ int width = srcImag ...
- 使用VS Code调试TypeScript游戏程序JsTankGame成功!!!
TypeScript游戏程序JsTankGame不是本人写的,是从CSDN下载的. JsTankGame是用Visual Studio开发的,因此在Visual Studio下调试非常顺畅.本人尝试用 ...
- C#异步编程的实现方式——ThreadPool线程池
在需要创建的线程很多,且都是比较小的线程的情况下,可以使用线程池(ThreadPool类).ThreadPool是一个静态方法,提供了对一个线程集合的操作,它会在线程数不足时增加线程,空闲线程数过多时 ...