Description
Bessie喜欢在手机上下游戏玩,然而她蹄子太大,很难在小小的手机屏幕上面操作。
她被她最近玩的一款游戏迷住了,游戏一开始有n个正整数,(2<=n<=262144),范围在1-40。在一步中,贝西可以选相邻的两个相同的数,然后合并成一个比原来的大一的数(例如两个7合并成一个8),目标是使得最大的数最大,请帮助Bessie来求最大值。
Sample Input
4
1
1
2
Sample Output
3
题目分析:
f[i][j]记录以i为左端点,合并成数j的区间长度
f[i][j+1]=(f[i][j],f[i+f[i][j]][j]) (i+f[i][j]<=n&&f[i][j]>0&&f[i+f[i][j]][j]>0)
DP的时候记录一下j+1的最大值就好了
因为序列里最多有218个数,两两合并,最大的数最多增加18,所以最大的数为58,所以i<=58。时间复杂度为O(58n)。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[270000][62];
int n;
int ans;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int tmp;
scanf("%d",&tmp);
f[i][tmp]=1;
ans=max(ans,tmp);
}
for(int j=1;j<=59;j++)
for(int i=1;i<=n;i++)
if(f[i][j]>0)
{
int tmp=f[i][j]+i;
if(tmp<=n&&f[tmp][j]>0)
{
f[i][j+1]=f[i][j]+f[tmp][j];
ans=max(ans,j+1);
}
}
printf("%d",ans);
}