[CCPC-Wannafly & Comet OJ 夏季欢乐赛(2019)]飞行棋
Posted sainsist
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CCPC-Wannafly & Comet OJ 夏季欢乐赛(2019)]飞行棋相关的知识,希望对你有一定的参考价值。
题目链接:https://www.cometoj.com/contest/59/problem/E?problem_id=2714
求期望并且一堆转移基本上就是期望dp了(叉腰
照常的设dp[i]表示i位置到n位置的期望步数。则我们所求的是dp[0]。
初始化dp[n]=0,因为n到n的期望为0。
之后先讨论下i为n-1到n-k的时候。
我们可以列出转移方程(随便写几个
$dp[n-1]=\tfrac1k*(dp[n]+dp[n-1]+dp[n-2]+\cdot \cdot \cdot +dp[n-k+1])+1$
$dp[n-2]=\tfrac1k*(dp[n-1]+dp[n]+dp[n-1]+\cdot \cdot \cdot +dp[n-k+2])+1$
$\cdot \cdot \cdot\cdot \cdot \cdot$
$dp[n-k]=\tfrac1k*(dp[n-k+1]+dp[n-k+2]+dp[n-k+3]+\cdot \cdot \cdot +dp[n])+1$
这时候自(mang)信(fu)同学可能就直接上高斯消元了,而善于发现的老哥则会很轻松的写出一组解,即:$dp[n-1]=dp[n-2]=dp[n-3]=\cdot \cdot \cdot =dp[n-k]=k$
之后再讨论下i为n-k-1到0的时候
就是很简单的转移:$dp[i]=\tfrac1k*(dp[i+k]+dp[i+k-1]+dp[i+k-2]+\cdot \cdot \cdot +dp[i+1])+1$
这里就可以直接矩阵快速幂优化。
先上一个8/15AC,7/15RE的不加速代码方便理解:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 using namespace std; 7 typedef long long ll; 8 const int maxn = 2e5 + 10; 9 const ll mod = 1000000007; 10 ll dp[maxn]; 11 ll qpow(ll a, ll b) 12 ll ans = 1; 13 while (b) 14 if (b & 1)ans = ans * a%mod; 15 a = a * a%mod; 16 b >>= 1; 17 18 return ans; 19 20 int main() 21 ll n, k; 22 cin >> n >> k; 23 ll inv = qpow(k, mod - 2); 24 dp[n] = 0; 25 ll sum = 0; 26 for (int i = n - 1; i >= n - k; i--) 27 dp[i] = k, sum = (sum + dp[i]) % mod; 28 for (int i = n - k - 1; i >= 0; i--) 29 dp[i] = (sum * inv + 1) % mod, sum = (sum - dp[i + k] + dp[i] + mod) % mod; 30 printf("%lld\n", dp[0]); 31
之后是本题正解:(先咕咕一下
以上是关于[CCPC-Wannafly & Comet OJ 夏季欢乐赛(2019)]飞行棋的主要内容,如果未能解决你的问题,请参考以下文章
洛谷 P1529 回家 Bessie Come Home Label:Dijkstra最短路 && 乱搞