洛谷P3147 DP-倍增

题目链接:https://www.luogu.com.cn/problem/P3147
题目大意:
在这里插入图片描述
思路:
我 们 用 f [ i ] [ j ] 表 示 从 位 置 j 开 始 合 并 成 一 个 数 i 的 最 远 位 置 。 怎 么 转 移 呢 ? 我 们 只 考 虑 i 由 两 个 i − 1 合 并 而 来 。 那 么 合 并 完 第 一 个 i − 1 的 位 置 f [ i − 1 ] [ j ] 。 那 么 第 二 个 i − 1 的 起 始 位 置 在 f [ i − 1 ] [ j ] , 终 点 在 f [ i − 1 ] [ f [ i − 1 ] [ j ] ] 所 以 f [ i ] [ j ] = m a x ( f [ i ] [ j ] , f [ i − 1 ] [ f [ i − 1 ] [ j ] ] ) p s : 为 什 么 只 考 虑 由 i − 1 合 并 而 来 。 如 果 能 够 由 更 小 的 数 合 并 , 那 么 一 定 先 合 并 成 了 i − 1 。 p s : i 的 最 大 值 为 什 么 为 58 。 如 果 全 部 是 40 。 最 多 合 并 成 40 + l o g 2 262144 = 58 。 \begin{array}{l} 我们用f[i][j]表示从位置j开始合并成一个数i的最远位置。怎么转移呢?\\\\ 我们只考虑i由两个i-1合并而来。那么合并完第一个i-1的位置f[i-1][j]。\\\\ 那么第二个i-1的起始位置在f[i-1][j],终点在f[i-1][f[i-1][j]]\\\\ 所以f[i][j]=max(f[i][j], f[i-1][f[i-1][j]])\\\\ ps:为什么只考虑由i-1合并而来。如果能够由更小的数合并,那么一定先合并成了i-1。\\\\ ps:i的最大值为什么为58。如果全部是40。最多合并成40+log_{2}^{262144}=58。 \end{array} f[i][j]jiii1i1f[i1][j]i1f[i1][j]f[i1][f[i1][j]]f[i][j]=max(f[i][j],f[i1][f[i1][j]])ps:i1i1ps:i584040+log2262144=58

#include <bits/stdc++.h>
#define LL long long
using namespace std;

int f[60][270000];
int main() {

    int n, x, ans=0; scanf("%d", &n);
    for(int i=1; i<=n; i++){
        scanf("%d", &x);
        f[x][i]=i+1;
    }
    for(int i=1; i<=58; i++){
        for(int j=1; j<=n; j++){

            f[i][j]=max(f[i][j], f[i-1][f[i-1][j]]);
            if(f[i][j]){
                ans=i;
            }
        }
    }
    cout<<ans<<endl;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值