C. Ayoub and Lost Array cf dp
Ayoub had an array aa of integers of size nn and this array had two interesting properties:
- All the integers in the array were between ll and rr (inclusive).
- The sum of all the elements was divisible by 33 .
Unfortunately, Ayoub has lost his array, but he remembers the size of the array nn and the numbers ll and rr , so he asked you to find the number of ways to restore the array.
Since the answer could be very large, print it modulo 109+7109+7 (i.e. the remainder when dividing by
The first and only line contains three integers nn , ll and rr (1≤n≤2?105,1≤l≤r≤1091≤n≤2?105,1≤l≤r≤109 ) — the size of the lost array and the range of numbers in the array.
OutputPrint the remainder when dividing by
2 1 3Output Copy
3Input Copy
3 2 2Output Copy
1Input Copy
9 9 99Output Copy
711426616Note
In the first example, the possible arrays are : [1,2],[2,1],[3,3][1,2],[2,1],[3,3] .
In the second example, the only possible array is [2,2,2][2,2,2] .
這個題目先要意識到這是一個動態規劃
他是在範圍內取一個元素個數為n,對3的余數為0的集合的方案數。
這個就可以當初一種動態規劃,從1到n轉移。
#include <iostream> #include <stdio.h> #include <stdlib.h> using namespace std; typedef long long ll; const int maxn=2e5+100; ll mod=1e9+7,dp[maxn][4];//dp[i][j]代表余數為j時,集合元素為i的方案數 int main() { int n,l,r,a=0,b=0,c=0; cin>>n>>l>>r; int k=(r-l)/3; a=b=c=k; for(int i=l+3*k;i<=r;i++) { if(i%3==0) a++; if(i%3==1) b++; if(i%3==2) c++; } dp[1][0]=a; dp[1][1]=b; dp[1][2]=c; for(int i=2;i<=n;i++) { dp[i][0]=dp[i-1][0]*a%mod; dp[i][0]%=mod; dp[i][0]+=dp[i-1][1]*c%mod; dp[i][0]%=mod; dp[i][0]+=dp[i-1][2]*b%mod; dp[i][0]%=mod; dp[i][1]=dp[i-1][0]*b%mod; dp[i][1]%=mod; dp[i][1]+=dp[i-1][1]*a%mod; dp[i][1]%=mod; dp[i][1]+=dp[i-1][2]*c%mod; dp[i][1]%=mod; dp[i][2]=dp[i-1][0]*c%mod; dp[i][2]%=mod; dp[i][2]+=dp[i-1][1]*b%mod; dp[i][2]%=mod; dp[i][2]+=dp[i-1][2]*a%mod; dp[i][2]%=mod; } cout<<dp[n][0]<<endl; return 0; }
C. Ayoub and Lost Array cf dp