题目
题解思路
集合定义
dp [ i ] [ 2 ]
考虑长度为i的合法串中以1或者0结尾的字符串数量
考虑的两种状态
即连着N*K个1并且以1结尾,或者以0结尾。
初始条件
dp[ 0 ] [ 0 ] = 1
dp[ k ] [ 1 ] = 1
转移
0的情况可以从前一个合法情况中以1 0 结尾转移
而
1的情况可以从i-k的以1为结尾的情况加K个1,或者在以0结尾的情况加K个1。
转移完了求个前缀和输出即可。
注意减法取模的影响。
AC代码
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<int,int>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7 ;
const int N = 100010 ;
long long dp[N][2] ;
long long sum[N] ;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
long long T , k ;
cin>> T >> k ;
dp[0][0] = 1 ;
dp[k][1] = 1 ;
for (int i = 1 ; i <= 100000 ; i++ )
{
if ( i - k >= 1 )
{
dp[i][1] = (dp[i-k][1] + dp[i-k][0] )%mod ;
}
dp[i][0] = ( dp[i-1][1] + dp[i-1][0] )% mod ;
}
/*
for (int i = 1 ; i <= 3 ; i++ )
{
cout << dp[i][0] << " " ;
}
cout << "\n" ;
for (int i = 1 ; i <= 3 ; i++ )
{
cout << dp[i][1] << " " ;
}
cout << "\n" ; */
for (int i = 1 ; i <= 100000 ; i++ )
{
sum[i] = (sum[i-1] + dp[i][0] + dp[i][1] )%mod ;
}
while (T--)
{
int t1 , t2 ;
cin >> t1 >> t2 ;
cout << sum[t2] - sum[t1-1] << "\n" ;
}
return 0 ;
}