牛客网 暑期ACM多校训练营(第二场)A.run-动态规划 or 递推?

牛客网暑期ACM多校训练营(第二场)

水博客。

A.run

题意就是一个人一秒可以走1步或者跑K步,不能连续跑2秒,他从0开始移动,移动到[L,R]的某一点就可以结束。问一共有多少种移动的方式。

个人感觉是带约束条件的超级楼梯问题。说是dp其实就是递推吧。只要连续的两秒不是跑的就可以。所以在已经跑了i步的时候,直接考虑最后一步是跑的还是走的就可以了。

所以公式就是dp[i]=dp[i-1]+dp[i-1-k];然后前缀和预处理一下,直接从L的for到R的就可以了。

反正乱七八糟就出来了。现在写题写的脑子都没了。

代码:

 1 //A
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<map>
 9 using namespace std;
10 typedef long long ll;
11 const int maxn=1e5+10;
12 const ll mod=1000000007;
13 ll dp[maxn],ans[maxn];
14 void init(int k)
15 {
16     for(int i=0;i<k;i++)
17         dp[i]=1;
18     dp[k]=2;
19     for(int i=k+1;i<maxn;i++)
20         dp[i]=(dp[i-1]+dp[i-k-1])%mod;
21     for(int i=1;i<maxn;i++)
22         ans[i]=(ans[i-1]+dp[i])%mod;
23 }
24 int main()
25 {
26     int q,k;
27     scanf("%d%d",&q,&k);
28     init(k);
29     while(q--){
30         int l,r;
31         scanf("%d%d",&l,&r);
32         printf("%lld
",(ans[r]-ans[l-1]+mod)%mod);
33     }
34 }

Come on,BABY.

原文地址:https://www.cnblogs.com/ZERO-/p/9358864.html