P1192台阶问题 题目描述 有N级的台阶,你一开始在底部,每次可以向上迈最多K级台阶(最少11级),问到达第N级台阶有多少种不同方式。

大家好!
第一次写代码,手抖----
下面写P1192台阶问题的解析即代码
这题关系式很明显,几乎是斐波那契数列
所以可以用递推来做
f(n) = f(n-1) + f(n-2) + f(n-3) + … + f( max(0,n-k) )
max保证了递推式对于前k项也成立,因为f不能作用一个负数
但是直接这么递推复杂度为O(nk),只能得到40分,后面的全部tle掉
于是需要用前缀和的思想进行优化,即pf(n) = f(n) + f(n-1) + f(n-2) + … + f(0)
然后就有f(n) = pf(n-1) - pf( max(0,n-k) - 1 ),定义pf(-1) = 0
但是要注意每次计算完pf和f都要膜一下
但是膜完之后可能两个pf相减是个负数,这时就要加上100003
不懂dalao们是如何裸的递推还不TLE的。。。反正裸的递推我是TLE了。
当然也可以用矩阵加速递推,由于太麻烦,这里就不在讨论
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int p = 100003;
ll rst[100010];
ll pf[100010];
int n,k;
ll getpf( int l , int r )
{
if( l == 0 ) return pf[r];
else
{
ll ret = pf[r] - pf[l-1];
if( ret < 0 ) ret += p;
return ret;
}
}
int main()
{
cin >> n >> k;
rst[0] = pf[0] = 1;
for( int i = 1 ; i <= n ; ++i )
{
int j = max(0,i-k);
rst[i] = getpf(j,i-1);
pf[i] = pf[i-1] + rst[i];
pf[i] %= p;
}
cout << rst[n] << endl;
return 0;
}

猜你喜欢

转载自blog.csdn.net/yanpanyan/article/details/89057983