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)的更多相关文章

  1. Codeforces Round #568 (Div. 2) G1. Playlist for Polycarp (easy version) (状压dp)

    题目:http://codeforces.com/contest/1185/problem/G1 题意:给你n给选项,每个选项有个类型和价值,让你选择一个序列,价值和为m,要求连续的不能有两个相同的类 ...

  2. ZOJ3802 Easy 2048 Again (状压DP)

    ZOJ Monthly, August 2014 E题 ZOJ月赛 2014年8月 E题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?proble ...

  3. 刷题向》关于第一篇状压DP BZOJ1087 (EASY+)

    这是本蒟蒻做的第一篇状压DP,有纪念意义. 这道题题目对状压DP十分友善,算是一道模板题. 分析题目,我们发现可以用0和1代表每一个格子的国王情况, 题目所说国王不能相邻放置,那么首先对于每一行是否合 ...

  4. Codeforces 544E Remembering Strings 状压dp

    题目链接 题意: 给定n个长度均为m的字符串 以下n行给出字符串 以下n*m的矩阵表示把相应的字母改动成其它字母的花费. 问: 对于一个字符串,若它是easy to remembering 当 它存在 ...

  5. 多米诺骨牌放置问题(状压DP)

    例题: 最近小A遇到了一个很有趣的问题: 现在有一个\(n\times m\)规格的桌面,我们希望用\(1 \times 2\)规格的多米诺骨牌将其覆盖. 例如,对于一个\(10 \times 11\ ...

  6. hdu 3247 AC自动+状压dp+bfs处理

    Resource Archiver Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Ot ...

  7. POJ 2411 Mondriaan's Dream -- 状压DP

    题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...

  8. 状态压缩动态规划 状压DP

    总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...

  9. TZOJ 2289 Help Bob(状压DP)

    描述 Bob loves Pizza but is always out of money. One day he reads in the newspapers that his favorite ...

随机推荐

  1. hadoop2.2.0的WordCount程序

    package com.my.hadoop.mapreduce.wordcount; import java.io.IOException; import org.apache.hadoop.conf ...

  2. Storm实现单词计数

    package com.mengyao.storm; import java.io.File; import java.io.IOException; import java.util.Collect ...

  3. 继承PictureBox显示GIF的自定义控件实现

    处理GIF部分 using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...

  4. 升级Android ADT 和SDK

    因为眼下从事android开发工作,所以升级了下Android SDK和eclipse ADT插件 一.更新ADT 1.Eclipse中打开Help->Install New Software. ...

  5. Nested Class Templates

      Templates can be defined within classes or class templates, in which case they are referred to as ...

  6. ETL几种方案对比

  7. LSI SAS 2308配置操作

    介绍LSISAS2308的配置操作 3.1 登录CU界面 介绍登录LSISAS2308的CU配置界面的方法. 3.2 创建RAID 介绍在LSISAS2308扣卡上创建RAID的操作方法. 3.3 配 ...

  8. windows身份验证,那么sqlserver的连接字符串的

    Data Source=计算机名称或ip地址;Initial Catalog=数据库名称;Integrated Security=True windows身份验证不需要psw的Provider=SQL ...

  9. JS 无提示关闭当前窗口

    function teseClose() { window.opener = null; window.open('','_self'); window.close(); }

  10. ViewPager欢迎页

    布局  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:to ...