zoukankan      html  css  js  c++  java
  • 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
    ", ans);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    是时候把邮件发送时间机动化处理了
    GDUT 初赛 01串也疯狂之光棍也有伴
    通达OA 尝试一下进行通达OA的培训
    不让政府系统用Windows 8,他们用什么?
    Mybatis自动生成插件对数据库类型为text的处理
    Mybatis自动生成插件对数据库类型为text的处理
    js的同步与异步
    js的同步与异步
    js的同步与异步
    Java中的数组与集合
  • 原文地址:https://www.cnblogs.com/yeahpeng/p/3938168.html
Copyright © 2011-2022 走看看