【题解】P3147 [USACO16OPEN]262144 P

题目链接(洛谷)

题目大意

有一种游戏,游戏一开始有n个正整数,$(2\le n\le 2^{18} )$,范围在$[1,40]$。在一步中,可以选相邻的两个相同的数,然后合并成一个比原来的大一的数(例如两个$7$合并成一个$8$),目标是使得最大的数最大,请求最大值。

分析

设$dp(i,j)$为左端点为$j$,合并出数字$i$时右端点的位置。通过下面数轴可以得出转移方程:

关于$i$的枚举范围,因为$n\le 2^{18}$,所以$i\le 40+18=58$

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<bits/stdc++.h>
using namespace std;
int dp[60][270000];
int n,a[270000];
int ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
dp[a[i]][i]=i+1;
}
for(int i=2;i<=58;i++){
for(int j=1;j<=n;j++){
if(!dp[i][j]) dp[i][j]=dp[i-1][dp[i-1][j]];
if(dp[i][j]) ans=i;
}
}
cout<<ans;
return 0;
}