luoguP3147 [USACO16OPEN]262144

Posted lylyl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP3147 [USACO16OPEN]262144相关的知识,希望对你有一定的参考价值。

这里有一种非常鬼畜的(dp)方法.

(dp[i][j])表示区间的最大值为$ i (,区间的起始点为) j $的区间长度.
[ herefore dp[i][j]=dp[i-1][j]+dp[i-1][j+dp[i-1][j]] ]
当然前提是(dp[i-1][j])(dp[i-1][j+dp[i-1][j]])能够取到.

答案是能够取到的(dp[I][J])(I)的最大值.

如何想到的呢?其实这是一个套路.

如果将(dp[i][j])设为区间起始点为(i),区间长度为(j)的最大值,(Then:)

(I'm happy to inform you that your test is MLE)(艹).

但是最大值的范围只有(log_2262144 +40=58).

于是我们可以对调(dp)的参数,于是就得到了这个鬼畜的(dp).

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define il inline
#define rg register
#define gi read<int>
using namespace std;
const int O = 1 << 18 | 10;
template<class TT>
il TT read() {
    TT o = 0,fl = 1; char ch = getchar();
    while (!isdigit(ch) && ch != '-') ch = getchar();
    if (ch == '-') fl = -1, ch = getchar();
    while (isdigit(ch)) o = o * 10 + ch - '0', ch = getchar();
    return fl * o;
}
int n, dp[58][O], ans;
int main() {
    n = gi();
    for (int i = 1; i <= n; ++i) dp[gi()][i] = 1;
    for (int i = 1; i <= 58; ++i)
        for (int j = n; j; --j)
            if (dp[i - 1][j] && dp[i - 1][j + dp[i - 1][j]]) {
                dp[i][j] = dp[i - 1][j] + dp[i - 1][j + dp[i - 1][j]];
                ans = max(ans, i);
            }
    printf("%d
", ans);
    return 0;
}

以上是关于luoguP3147 [USACO16OPEN]262144的主要内容,如果未能解决你的问题,请参考以下文章

题解 P3147 [USACO16OPEN]262144

luogu P3147 [USACO16OPEN]262144

P3147 [USACO16OPEN]262144

[luoguP3146] [USACO16OPEN]248(区间DP)

[LuoguP3668][USACO17OPEN]现代艺术2

[luoguP3668] [USACO17OPEN]Modern Art 2 现代艺术2(栈)