P3147 [USACO16OPEN]262144 P(dp)
作者:互联网
目录
Description
每两个相邻的数 \(x\) 可以合并成一个数 \(x+1\),求最后剩下的数中最大的值
State
\(2<=n<=262144\)
\(1<=a[i]<=40\)
Input
4
1
1
1
2
Output
3
Solution
如果数据范围足够小题目完全可以区间 \(dp\);
发现这道题的值域很小,不妨可以利用 \(dp\) 来表示是否可以凑出 \(i\),并寻找 \(i\) 的最大值;
但只有一维是远远不够的,令 \(dp[i][j]\) 为区间 \([j,dp[i][j]]\) 可以合并为 \(i\),知道了 \(dp[i][j]\) 之后其实是很有用的,下一步就是如何 \(i->i+1\);
直接给出方程: \(dp[i+1][j]=dp[i][dp[i][j]+1]\)
这样一步步推下去,如果 \(dp[i][j]!=0\) 就可以知道最大的 \(i\) 是多少了
Code
const int N = 3e5 + 5;
int n, m, k, _;
int a[N];
int dp[60][N];
signed main()
{
// IOS;
while(~ sd(n)){
rep(i, 1, n) sd(a[i]);
for(int i = 1; i <= n; i ++){
dp[a[i]][i] = i;
}
int ans = 0;
for(int i = 1; i <= 58; i ++){
for(int j = 1; j <= n; j ++){
if(dp[i - 1][j] && dp[i - 1][dp[i - 1][j] + 1])
dp[i][j] = dp[i - 1][dp[i - 1][j] + 1];
if(dp[i][j])
ans = i;
}
}
pd(ans);
}
// PAUSE;
return 0;
}
标签:int,Solution,262144,State,USACO16OPEN,Input,dp,sd 来源: https://www.cnblogs.com/Segment-Tree/p/15376922.html