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; }