USACO 2016 Open Platinum 1.262144

题目描述

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

 

发表评论

邮箱地址不会被公开。 必填项已用*标注