1. 程式人生 > 其它 >牛客2018暑假多校訓練營2

牛客2018暑假多校訓練營2

牛客2018暑假多校訓練營2

比賽連結

牛客2018暑假多校訓練營2

題目描述

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.

輸入描述:

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

解題思路

dp

  • 狀態表示:\(f[i][0/1]\) 表示行進了 \(i\) 米,且最後一步是走/跑的方案數
  • 狀態計算:
    \(f[i][0]=f[i-1][0]+f[i-1][1]\)
    \(f[i][1]=f[i-k][0]\)

分析:無論是走還是跑,每秒都有一個最終狀態,dp列舉的就是這個最終狀態,但這個最終狀態是走時,前一個狀態可能是走,也可能是跑;最終狀態是跑時,前一個狀態只能是走~
用一個字首和陣列 \(s\) 維護 \(0\sim i\) 的所有方案數,求 \(l\sim r\) ,即 \(s[r]-s[l-1]\)

  • 時間複雜度:\(O(10^5)\)

程式碼

//dp
//狀態表示:f[i][0/1]表示走了i米,最後是跑的(1)還是走的(0)
//狀態計算:f[i][0]=f[i-1][0]+f[i-1][1]
//         f[i][1]=f[i-k][0]
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int f[100010][2],s[100010];
int q,k;
int main()
{
    scanf("%d%d",&q,&k);
    f[0][0]=1;
    for(int i=1;i<=100000;i++)
    {
        f[i][0]=(f[i][0]+f[i-1][0]+f[i-1][1])%mod;
        if(i>=k)f[i][1]=(f[i][1]+f[i-k][0])%mod;
    }
    for(int i=1;i<=100000;i++)
        s[i]=(s[i-1]+f[i][0]+f[i][1])%mod;
    while(q--)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        printf("%d\n",(s[r]-s[l-1]+mod)%mod);
    }
    return 0;
}