Easy 2048 Again(状压dp)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3802

题意: 从数列A中, 删除若干个数(可以0个), 是删除后的数列, 进行类似  Flappy 2048 游戏的运算, 使结果最大, 求该最大值。

题解: 每个数ai, 取或不取, 满足 可用二进制表示。 当 ai < a[i + 1] 是, 易想到 如果两个数都取, ai 将不会在合并。 所以只需考虑ai[i + 1] 前的 降序列即可 .如果没个数都为16, 合并后的数列的最大值为4026 = 2^12。 也就是说, a[i + 1]最多只需考虑 合并到a[i +1]为后的前 12项。

具体的看 代码吧

 1 /***Good Luck***/
 2 #define _CRT_SECURE_NO_WARNINGS
 3 #include <iostream>
 4 #include <cstdio>
 5 #include <cstdlib>
 6 #include <cstring>
 7 #include <string>
 8 #include <algorithm>
 9 #include <stack>
10 #include <map>
11 #include <queue>
12 #include <vector>
13 #include <set>
14 #include <functional>
15 #include <cmath>
16
17 #define Zero(a) memset(a, 0, sizeof(a))
18 #define Neg(a)  memset(a, -1, sizeof(a))
19 #define All(a) a.begin(), a.end()
20 #define PB push_back
21 #define inf 0x3f3f3f3f
22 #define inf2 0x7fffffffffffffff
23 #define ll long long
24 using namespace std;
25 //#pragma comment(linker, "/STACK:102400000,102400000")
26
27 const int mw = 1 << 13;
28 int n;
29 int arr[mw]; // 滚动数组
30 int mx;
31 inline int add(int i, int v) {
32     int tmp = ((i + v) | i) - i ;
33     int ans = v;
34     while (v < tmp) {
35         ans = ans + (v <<= 1);
36     }
37     return ans;
38 }
39 void cal(int v) {
40     int tmpv;
41     int tmpmx  = 0;
42     for (int i = mx; i >= 0; --i) {  //mx 记录每次cal 时, 改动的最大值。 (不知为什么, 没优化这一步, 超时, 优化后 10ms,相差好大)
43         if ((i & (v - 1))) {
44             tmpmx = max(tmpmx, arr[i]);  // 记录 arr[i + 1] > arr[i]中的多种情况 下的最大得分。
45             continue;
46         }
47         if (arr[i] && arr[i + v] < arr[i] + (tmpv = add(i,v))) { // 计算并更新arr[i + 1] <= arr[i]中多种情况
48             arr[i + v] = arr[i] + tmpv;
49             mx = max(i + v, mx);         // 记录该次运行时所用的最大 数。
50         }
51     }
52     arr[v] = v + tmpmx;
53     mx = max(v, mx);
54 }
55
56 int main() {
57     int T;
58     scanf("%d", &T);
59     while (T--) {
60         Zero(arr);
61         int val = 0;
62         scanf("%d", &n);
63         scanf("%d", &val);
64         mx = val;         //第一次的范围
65         cal(val);
66         for (int i = 2; i <= n; ++i) {
67             scanf("%d", &val);
68             cal(val);
69         }
70         int ans = 0;
71         for (int i = 0; i < mw; ++i) ans = max(ans, arr[i]);
72         printf("%d\n", ans);
73     }
74     return 0;
75 }
时间: 2024-10-27 02:42:04

Easy 2048 Again(状压dp)的相关文章

ZOJ 3802 Easy 2048 Again 状压DP

直接从前往后DP,因为一共只有500个数,所以累加起来的话单个数不会超过4096,并且因为是Flappy 2048的规则,所以只有之后数列末尾一串递减的是有效的,因此可以状压. 1700ms = =,据说用滚动数组优化一下会好很多 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector>

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

题目:http://codeforces.com/contest/1185/problem/G1 题意:给你n给选项,每个选项有个类型和价值,让你选择一个序列,价值和为m,要求连续的不能有两个相同的类型,相同的物]品不一样的顺序代表不同,问有多少个序列 思路:首先范围是15个,这里我们可以用状压来代表选择哪些物品,然后这里是说不能有连续相同的类型,这里我们贪心考虑不全,最开始我考虑的是组合数的插空法,当时 发现有很多细节,写不了,这样的话我们就只能改成dp, 我们设置dp[i][j]   代表i

ZOJ3802 Easy 2048 Again (状压DP)

ZOJ Monthly, August 2014 E题 ZOJ月赛 2014年8月 E题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5334 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

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 显然全部记录是不可能的.那么怎么处理呢 我们发现,只有递减的序列才有可能向前合

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

这是本蒟蒻做的第一篇状压DP,有纪念意义. 这道题题目对状压DP十分友善,算是一道模板题. 分析题目,我们发现可以用0和1代表每一个格子的国王情况, 题目所说国王不能相邻放置,那么首先对于每一行是否合法的判断条件就出来了:就是对于情况X,如果X&(x<<1)==0,即为合法情况. 同理这样我们就可以得出每一行对于上一行是否合法的条件:(x&y)==0&&(x&(y<<1))==0&&(x&(y>>1))==

Codeforces 544E Remembering Strings 状压dp

题目链接 题意: 给定n个长度均为m的字符串 下面n行给出字符串 下面n*m的矩阵表示把对应的字母修改成其他字母的花费. 问: 对于一个字符串,若它是easy to remembering 当 它存在一个字母,使得这个字母在这一列是独一无二的. 要使得n个字符串都是easy to remembering 的最小花费. 第一个样例是把第一列的4个a中3个a修改成别的字母,所以花费为3. 思路: 显然是个状压dp,但需要一点转化. 首先得到一个结论: 对于某一列,设这一列的字母是 a,a,b,b,a

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

Resource Archiver Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others)Total Submission(s): 2382    Accepted Submission(s): 750 Problem Description Great! Your new software is almost finished! The only thing left to

HDU-3502-Huson&#39;s Adventure Island(BFS+状压DP)

Problem Description A few days ago, Tom was tired of all the PC-games, so he went back to some old FC-games. "Hudson's Adventure Island" was his favorite which he had played thousands of times. But to his disappointed, the more he played, the mo

poj 2441 Arrange the Bulls(状压DP入门)

Arrange the Bulls Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 3509   Accepted: 1344 Description Farmer Johnson's Bulls love playing basketball very much. But none of them would like to play basketball with the other bulls because the

ICPC2018南京网络赛 AC Challenge(一维状压dp)

AC Challenge 30.04% 1000ms 128536K Dlsj is competing in a contest with n (0 < n \le 20)n(0<n≤20) problems. And he knows the answer of all of these problems. However, he can submit ii-th problem if and only if he has submitted (and passed, of course)