P3147 [USACO16OPEN]262144 (贪心)

题目描述

  给定一个1*n的地图,在里面玩2048,每次可以合并相邻两个(数值范围1-262,144),问最大能合出多少。注意合并后的数值并非加倍而是+1,例如2与2合并后的数值为3.  

  这道题的思路:

  这是上一道题的数据强化版,数据达到了 260000.

  所以只能 O(nlogn) 的时间复杂度过.

  然后就发现根本就已经不是一道题目了,方程和处理方式完全不一样.

    非动规版本 

  非动规版本是动用了一个数据结构---栈. 比较巧妙.

  因为这道题有带一点贪心的思想在里面,因为所有的元素就只有那些,所以无论怎么合并,都会把能合并都合并都合并完.

  关于顺序的话,正着来一遍,再到着来一遍即可.在栈中选取最大值.

       代码

#include<bits/stdc++.h>
using namespace std;
int n,d[263000],kkp[263000],num,ans;
void insert(int x)
{
    kkp[++num]=x;
    while(kkp[num]==kkp[num-1])                  
    num--,kkp[num]=kkp[num+1]+1;
    //一旦一个元素进入栈中 
    //那么就将它和它相邻的一直合并到一个都不剩.
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&d[i]);
    for(int i=1;i<=n;i++)
    insert(d[i]);
    for(int i=1;i<=num;i++)
    ans=max(kkp[i],ans);
      num=0;
    for(int i=n;i>=1;i--)
    insert(d[i]);                                 //倒序再来一遍.
    for(int i=1;i<=num;i++)
    ans=max(kkp[i],ans);
    cout<<ans;
    return 0;
}

动规版本暂时还没研究... 日后再填.

原文地址:https://www.cnblogs.com/Kv-Stalin/p/8869346.html