初始时,你的位置在0,每次第i次移动时必须让你的位置增长t,t是k+i的倍数。
现在求1到n的所有x,从0到x的不同路径有多少条。访问位置集不同则视为路径不同。
">Chip Move
Chip Move
Created by LXC on Wed Aug 30 09:48:18 2023
https://codeforces.com/problemset/problem/1716/D
ranting: 2000
tag: brute force, dp, math
problem
初始时,你的位置在0,每次第i次移动时必须让你的位置增长t,t是k+i的倍数。
现在求1到n的所有x,从0到x的不同路径有多少条。访问位置集不同则视为路径不同。
solution
最少会移动多少次?假设最少移动m次到达x,那么$k + k+1 + k+2 + \cdots + k+m-1 = x$,显然m是$O(\sqrt x)$级别的
设$f_{i,j}$为上一次移动距离为j到达i的所有路径数。
$f$的总状态数为$O(n\sqrt n)$,我们每次转移的时间复杂度看样子得$O(1)$才能不超时。
状态转移,在已知$f_{?,j-1}$可以求得$f_{?,j}$
$f_{i,j}=f_{i-j, j-1}+f_{i-2j,j-1}+f_{i-3j, j-1} + \cdots + f_{i\bmod j, j-1}$,看样子会超时。
实际上我们可以对于前缀中模k同余的索引,用哈希表进行维护。一边遍历、一边更新、一边查询。做到$O(1)$时间复杂度转移。
总时间复杂度为状态数乘以每个状态转移时间,$O(n \sqrt n)$
注意空间复杂度会超出限制,$f_{?,j}$只依赖于$f_{?,j-1}$,可以利用滚动数组做到$O(n)$空间。
code
1 |
|