水博客。
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.