2018牛客网暑期ACM多校训练营(第二场) A - run - [DP]
题目链接:https://www.nowcoder.com/acm/contest/140/A
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
White Cloud is exercising in the playground.
White Cloud can walk 1 meters or run k meters per second.
Since White Cloud is tired,it can't run for two or more continuous seconds.
White Cloud will move L to R meters. It wants to know how many different ways there are to achieve its goal.
Two ways are different if and only if they move different meters or spend different seconds or in one second, one of them walks and the other runs.
White Cloud can walk 1 meters or run k meters per second.
Since White Cloud is tired,it can't run for two or more continuous seconds.
White Cloud will move L to R meters. It wants to know how many different ways there are to achieve its goal.
Two ways are different if and only if they move different meters or spend different seconds or in one second, one of them walks and the other runs.
输入描述:
The first line of input contains 2 integers Q and k.Q is the number of queries.(Q<=100000,2<=k<=100000)
For the next Q lines,each line contains two integers L and R.(1<=L<=R<=100000)
输出描述:
For each query,print a line which contains an integer,denoting the answer of the query modulo 1000000007.
输入
3 3 3 3 1 4 1 5
输出
2 7 11
题意:
有个人现在有两种行进方式:1、走路,速度 1 m/s;2、跑步,速度 k m/s,但是跑步不能持续两秒及以上。
现在这个人目标是跑[L,R]米,请问他有多少种方式完成?
题解:
假设这个人从0米出发,只能往右跑,只要到达[L,R]区间即可,
我们设:
dp[i][0]:最后一步是跑着到 i 米的方案数。
dp[i][1]:最后一步是走着到 i 米的方案数。
那么我们可以先一次性把所有dp[i][0]和dp[i][1]做出来,然后对于每个查询,答案就是$\sum\limits_{i = L}^R {\left( {dp\left[ i \right]\left[ 0 \right] + dp\left[ i \right]\left[ 1 \right]} \right)} $。
同时,考虑到如果每次查询都要求一次和比较浪费时间,所以用前缀和数组$sum\left[ i \right] = \sum\limits_{k = 0}^i {\left( {dp\left[ k \right]\left[ 0 \right] + dp\left[ k \right]\left[ 1 \right]} \right)} $。
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAX=100000+3; const ll MOD=1000000007; int Q,k; int L,R; ll dp[MAX][2]; //dp[i][0]:最后一步是跑着到 i 米的方案数。 //dp[i][1]:最后一步是走着到 i 米的方案数。 ll sum[MAX]; int main() { scanf("%d%d",&Q,&k); memset(dp,0,sizeof(dp)); dp[0][0]=1, dp[0][1]=0; for(int i=0;i<=MAX;i++) { dp[i+k][1]+=dp[i][0]; dp[i+k][1]%=MOD; dp[i+1][0]+=dp[i][0]+dp[i][1]; dp[i+1][0]%=MOD; } sum[0]=0; for(int i=1;i<=MAX;i++) { //printf("%d: %lld %lld\n",i,dp[i][0],dp[i][1]); sum[i]=(sum[i-1]+(dp[i][0]%MOD+dp[i][1]%MOD)%MOD)%MOD; } for(int q=1;q<=Q;q++) { scanf("%d%d",&L,&R); printf("%lld\n",((sum[R]-sum[L-1])+MOD)%MOD); } }
转载请注明出处:https://dilthey.cnblogs.com/