VOJ 跳一跳 题解 动态规划

跳一跳

题目描述

现有一排方块,依次编号为 1 … n 1\ldots n 1n
方块 1 上有一个小人,已知当小人在方块 i 上时,下一秒它会等概率地到方块 i(即不动),方块 i+1,方块 i+2……方块 n 上。
求小人到达方块 n 所需要的期望时间(单位:秒)。

输入格式

一个数字 n。

输出格式

若答案 a n s = A B ans=\frac{A}{B} ans=BA 输出 A × B − 1   m o d   ( 1 0 9 + 7 ) A \times B^{-1} \bmod (10^9+7) A×B1mod(109+7)。其中 B − 1 B^{-1} B1 表示 B   m o d   ( 1 0 9 + 7 ) B \bmod (10^9+7) Bmod(109+7) 下的逆元。

样例 1

输入样例

1

输出样例

0

样例 2

输入样例

10000000

输出样例

406018741

数据范围与约定

对于 50 % 50\% 50% 的数据, n ⩽ 1 0 6 n \leqslant 10^6 n106
对于 100 % 100\% 100% 的数据, 1 ⩽ n ⩽ 1 0 7 1 \leqslant n \leqslant 10^7 1n107

思路

d p [ i ] dp[i] dp[i]为从 i 点出发到达 n 点的期望时间,然后从后向前递推。

原题

LOJ6342——传送门

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7 + 6;
const ll mod = 1e9 + 7;
int inv[maxn]; // 逆元
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    inv[0] = 1;
    inv[1] = 1;
    for (int i = 2; i <= n; i++) // 预处理逆元
        inv[i] = mod - mod / i * inv[mod % i] % mod;
    ll dp = 0;  // 为了避免MLE,不能开dp数组
    ll sum = 0; // sum记录后缀和
    for (int i = n - 1; i >= 1; i--)
    {
        dp = (sum + n - i + 1) * inv[n - i] % mod;
        sum += dp;
        sum %= mod;
    }
    cout << dp << '\n';
    return 0;
}
  • 22
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值