USACO 2016 US Open Contest 262144 (bzoj4576)

262144 (262144)
 
Description
Bessie喜欢在她的手机上下载游戏玩,尽管她发现她的大蹄使用小触摸屏幕相当麻烦。她特别感兴趣的是她正在玩
的游戏。 游戏从一个有N个正整数的序列开始(2≤N≤262,144),每个数字在1...40的范围内。 在一个步骤中,
Bessie可以获取具有相等值的两个相邻数字,并且用比这两个数大一的值替换这两个数值(例如,她可以用8替换
两个相邻的7)。目标是在游戏结束时最大化在序列中存在的最大数字的值。 请帮助Bessie得分尽可能高!
 
题目大意:
给定一个长度为n(n<=2^18)的序列,初始元素值为1到40之间的整数,每次操作可以将两个相邻的并且大小相同
的正整数替换成一个比原数大一的正整数。要求最大化最终数列中的最大值。

dp f[i][j]表示以j为左端合成i的右端点位置。转移即可。
 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <queue>
 6 #include <vector>
 7 using namespace std;
 8 const int maxn=3e5+10;
 9 int n,ans;
10 int f[60][maxn];
11 template <class T> void read(T&x)
12 {
13   x=0;char c=getchar();int f=0;
14   while(c<'0'||c>'9'){f|=(c=='-');c=getchar();}
15   while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
16   x=f?-x:x;
17 }
18 int main()
19 {
20   read(n);int a;
21   for(int i=1;i<=n;i++){read(a);f[a][i]=i+1;}
22   for(int i=2;i<=58;i++)
23    for(int j=1;j<=n;j++)
24    {
25         if(!f[i][j])f[i][j]=f[i-1][f[i-1][j]];
26      if(f[i][j])ans=max(i,ans);
27    }
28   printf("%d",ans);
29   return 0;
30 } 
View Code

 

posted @ 2018-07-13 12:32  新手-周  阅读(321)  评论(0编辑  收藏  举报