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 ...
随机推荐
- RequireJS 2.0 新特性
就在前天晚上RequireJS发布了一个大版本,直接从version1.0.8升级到了2.0.随后的几小时James Burke又迅速的将版本调整为2.0.1,当然其配套的打包压缩工具r.js也同时升 ...
- JS浏览器对象-History对象
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- jq指定行切换
function G(){ var item=$('.req_list_item>li'); item.find($('.req_show')).hover(function(){ $(this ...
- Ubuntu16.04下部署 nginx+uwsgi+django1.9.7(虚拟环境pyenv+virtualenv)
由于用的新版本系统,和旧的稍有差别,在网上搜了很多相关资料,搞了三天终于搞好在Ubuntu16.04下的部署,接下来就详细写写步骤以及其中遇到的问题.前提是安装有虚拟环境pyenv+virtualen ...
- TypedArray和obtainStyledAttributes使用
在编写Android自定义按钮示例基础上,如果要指定字体大小产生这样的效果: 其实是不需要自定义变量的,可以直接使用TextView的配置属性: <com.easymorse.textbutto ...
- Java基础知识强化46:StringBuffer类之判断一个字符串是否对称案例
1. 分析:判断一个字符串是否是一个对称的字符串,我们只需要把字符串的第1个字符和最后1个字符,第2个字符和倒数第2个字符,…… 比较的次数是长度除以2. 方法1:通过取取索引对应值来进行一一比对 ...
- 国外十个出名的 upload 上传组件
在日常开发中,我们常会用到很多的组件及共用代码提高我们的开发效率. King MEDIA - $ 17.00 / 11 Sales DNNStore | 6/5/2014 6:06:42 PM| ...
- linux下登录出现-bash-3.2#解决办法
1:下载 安装 csh yum install csh 2:再切换即可
- Sql时间函数
一.sql server日期时间函数 Sql Server中的日期与时间函数 1. 当前系统日期.时间 select getdate() 2. dateadd 在向指定日期加上一段时间 ...
- JS将图片文件转为64位字符串再post到接口上传图片
HTML: <div class="ai-item upload-id-img"> <p>上传身份证照片</p> <div class=& ...