洛谷P3147 [USACO16OPEN]262144 P

题目:

游戏一开始有n个正整数,(2<=n<=262144),范围在1-40。

在一步中,贝西可以选相邻的两个相同的数,然后合并成一个比原来的大一的数(例如两个7合并成一个8),目标是使得最大的数最大,请帮助Bessie来求最大值。

题解:

合成一个i,需要两个相邻的i-1,f[i][j]表示以j为左端点合并出i时的右端点

f[i][j]=f[i-1][f[i-1][j]+1],还有i的最大值根据n=2^18,设数组全为40,i最大为40+18=58

 

 代码:

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define check system("pause")
#define all(x) (x).begin(),(x).end()
#define de(a) cout<<#a<<" = "<<a<<endl
#define dd(a) cout<<#a<<" = "<<a<<" "
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define lowbit(a) ((a)&-(a))
#define INF 0x3f3f3f3f
const ll mod = 1e9+7;
const int N = 1e6+20;
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define mes(p,b) memset(p,b,sizeof(p))
#define sz(x) int(x.size())
int n,f[60][262145];
int main()
{
      ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
      cin>>n;
      int ans=0;
      mes(f,0);
      rep(i,1,n){
          int x;
          cin>>x;
          ans=max(ans,x);
          f[x][i]=i;
      } 
    rep(i,1,58)
        rep(j,1,n)
            if(f[i-1][j]>0&&f[i-1][f[i-1][j]+1]>0)
                  ans=i,f[i][j]=f[i-1][f[i-1][j]+1]; 
    cout<<ans; 
      return 0;
}

 

posted @ 2020-03-11 20:15  FZU_LH  阅读(197)  评论(0编辑  收藏  举报