Easy 2048 Again


Time Limit: 2 Seconds      Memory Limit: 65536 KB


Dark_sun knows that on a single-track road (which means once he passed this area, he cannot come back again), there are some underground treasures on each area of the road which has the
value of 2, 4, 8 or 16. Dark_sun can decide whether to dig them or not in order to get the highest score. The calculation rule of the total score is similar to the game Flappy 2048.

Dark_sun's bag is like a queue. When he gets a treasure, the treasure will be pushed back into the end of the bag. And the score will add the value of the treasure. For example, when
there are treasures on the road in the order of {2, 8, 4, 8} and if Dark_sun decides to dig all of them, he will get the final score of 2+8+4+8=22. And his bag will finally become the sequence of {2, 8, 4, 8}.

If the adjacent treasures in the Dark_sun's bag have the same value, they will mix into a bigger treasure which has the value of their sum (the double value of the previous one). And
Dark_sun will get a combo score of the value of bigger treasure. For example in the previous case, if Dark_sun decides to dig only the {2, 8, 8} treasure in sequence. He will get the basic score of 18(2+8+8). And when the last treasure (value 8) is pushed
back into his bag, his bag will turn {2, 8, 8} into {2, 16} and he will get a bonus score of 16. And his final score will become 18+16=34 (which is the best strategy in this case.)

Notice that the treasures mix to the bigger one automatically when there are the same adjacent treasures. For example, when there are treasures of {2, 2, 4, 8, 16} on the road, and if
Dark_sun decides to dig all of them, he will get the basic score of 32(2+2+4+8+16) and a bonus score of 60(4+8+16+32). At last he will get the total score of 92 and the bag becomes {32}.

Now, Dark_sun wants to get the highest score (no matter what's the treasure in his bag), can you tell him the what's the highest score?

Input

The first line is an integer n, which is the case number. In each case, the first line is an integer L, which is the length of the road.(0 < L ≤ 500)
The second line contains L integers which can only be 2, 4, 8 or 16. This means the value of treasure on each area of the road.

Output

For each case, you should output an integer. The answer is the maximum of the total score which Dark_sun may get.

Sample Input

3
4
2 8 4 8
5
2 2 4 8 16
8
8 4 4 2 8 4 2 2

Sample Output

34
92
116

Hint

In the third sample case, Dark_sun will choose {8,4,4,8,4,2,2}. Firstly, the first three treasures will be combined to 16 and then the {16,8,4,2,2} will become 32. And he will get the
basic score 32(8+4+4+8+4+2+2) and the bonus score 84(8+16+4+8+16+32).

题意:对于一个序列,你能够按顺序选或不选一些数。然后放在一个栈里。假设两个一样的数在一起就会合并,你的得分是放的数加上合并成的数的总和,问最后得分最多是多少。

思路:状压dp,这道题本身就是二进制,也就方便了,注意要用滚动数组。不然会爆MLE。

这里用滚动数组记录你在选第n个数的时候之前的状压情况和得分。

AC代码例如以下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
map<ll,ll> match[2];
ll F[1000010][2];
int vis[1000010];
ll ans;
void solve(ll S,ll k,int pos,int pos2)
{ F[0][pos2]++;
F[F[0][pos2]][pos2]=S; //不选这个数,保留原状压情况
match[pos2][S]=max(match[pos2][S],match[pos][S]);
if((S%k)!=0) //选这个数。而且之前状压情况有比k小的数。比方之前的状压结果为8 4 2 这时你增加一个4,那么队列里面就会是 8 4 2 4,
//前三个数都不可能再去合并了。所以状压结果仅仅要保留k就能够了
{ match[pos2][k]=max(match[pos2][k],match[pos][S]+k);
F[0][pos2]++;
F[F[0][pos2]][pos2]=k;
ans=max(ans,match[pos2][k]);
return;
}
ll ret=k,S2=S;
while((S&k)!=0) //合并同样的数
{ S-=k;
k*=2;
ret+=k;
}
S+=k;
match[pos2][S]=max(match[pos2][S],match[pos][S2]+ret);
ans=max(ans,match[pos2][S]);
F[0][pos2]++;
F[F[0][pos2]][pos2]=S;
}
int main()
{ int t,n,i,j,k,len,a,b,pos=0;
scanf("%d",&t);
while(t--)
{ scanf("%d",&n);
match[0].clear();match[1].clear();
F[0][0]=1;F[1][0]=0;
match[0][0]=0;
ans=0;
for(i=1;i<=n;i++)
{ pos++;
scanf("%lld",&k);
if(i&1)
{ a=0;b=1;}
else
{ a=1;b=0;}
match[b].clear();
F[0][b]=0;
for(j=1;j<=F[0][a];j++) // F[0][a]记录之前有多少种情况
if(vis[F[j][a]]!=pos)
{ solve(F[j][a],k,a,b); //对之前状压结果为F[j][a]的情况考虑选或不选这个数的结果
vis[F[j][a]]=pos;
}
}
printf("%lld\n",ans);
}
}

版权声明:本文博客原创文章。博客,未经同意,不得转载。

Easy 2048 Again - ZOJ 3802 像缩进dp的更多相关文章

  1. ZOJ3802 Easy 2048 Again (状压DP)

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

  2. HDU 3681 BFS&amp;像缩进DP&amp;二分法

    N*M矩阵.从F出发点.走完全部Y点.每个人格开支1电源点,去G点,电池充满,D无法访问.最小的开始问什么时候满负荷可以去完全部Y.Y和G总共高达15一 第一BFS所有的F.Y.G之间的最短距离. 然 ...

  3. ZOJ Problem Set - 3822Domination(DP)

    ZOJ Problem Set - 3822Domination(DP) problemCode=3822">题目链接 题目大意: 给你一个n * m的棋盘,每天都在棋盘上面放一颗棋子 ...

  4. ZOJ 3802 Easy 2048 Again 像缩进DP

    链接:problemId=5334">http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5334 题意:一个长度为5 ...

  5. ZOJ 3802 Easy 2048 Again 状态DP

    zoj 上次的月赛题,相当牛的题目啊,根本想不到是状态压缩好吧 有个预先要知道的,即500个16相加那也是不会超过8192,即,合并最多合并到4096,只有2的12次方 所以用状态压缩表示前面有的序列 ...

  6. zoj3802:easy 2048 again(状压dp)

    zoj月赛的题目,非常不错的一个状压dp.. 题目大意是一个一维的2048游戏 只要有相邻的相同就会合并,合并之后会有奖励分数,总共n个,每个都可以取或者不取 问最终得到的最大值 数据范围n<= ...

  7. Easy 2048 Again(状压dp)

    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3802 题意: 从数列A中, 删除若干个数(可以0个), 是删除 ...

  8. zoj 3537 Cake 区间DP (好题)

    题意:切一个凸边行,如果不是凸包直接输出.然后输出最小代价的切割费用,把凸包都切割成三角形. 先判断是否是凸包,然后用三角形优化. dp[i][j]=min(dp[i][j],dp[i][k]+dp[ ...

  9. ZOJ 3623 Battle Ships DP

    B - Battle Ships Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Subm ...

随机推荐

  1. Delphi中WebBrowser自动填表模板

    unit Unit1;interfaceuses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ...

  2. mongodb查询分页优化

    要求不用skip 前提:1.时间倒序排列(自己现在的项目中也是按照时间倒序排列的)       2.每页显示10条数据 int limit = 10;//刚开始点击查询的时候设置十条 查询形式为 db ...

  3. C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET

    C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...

  4. iOS 如何创建单例对象

    一.什么是单例? 说到单例我就想起了我的java啊 ,不禁感叹起我的大学时光,学了4年的java开发,到现在还是放弃了我的java,踏入了iOS的行列. 算了,入正轨,我现在正是铁树银花的青春美少女, ...

  5. 欧拉计划&#183;第四题

    题目4:找出由两个三位数乘积构成的回文. 一个回文数指的是从左向右和从右向左读都一样的数字.最大的由两个两位数乘积构成的回文数是9009 = 91 * 99. 找出最大的有由个三位数乘积构成的回文数. ...

  6. GIT的下载、安装、与使用

    一.下载: 网址:https://code.google.com/p/msysgit/ 进入这个网站以后,你会看到以下界面: 在这个界面中找到: 这时你便可以下载GIT 二.安装 安装过程比较简单,一 ...

  7. JSON支持什么对象/类型?

    原文:JSON支持什么对象/类型? 当一个面试官问你: JSON都支持什么对象/类型?你怎么回答? 也许他的本意是下面这个答案: JSON格式支持的数据类型有以下: 类型 描述 Number 在Jav ...

  8. Android开发 更改返回button的图标

    非常多的Android应用左上角都有返回button 在默认的情况下 ADT会默认给一个返回图标 而作为开发需求 非常多都要求定制一个新的图标 在Android的站点上 发现了2种能够更改的方法 1. ...

  9. 命令含执行JAVA程序

    1.当类没有包名时 javac Test.java java Test   2.当有包名情况下 package com.me.Test; javac -d . Test.java java com.m ...

  10. 如何解决This system is not registered with RHN.

    今天我必须写下这篇文章,由于在我刚刚接触到Linux下安装oracle时碰到了Linux中少xscreensaver.rpm包自己弄了非常久.最后还是被一个大哥帮我攻克了:仅仅能说非常的感谢你! 我试 ...