C. Ayoub and Lost Array(DP)
(又是被队友带着上分的一场--)
题目链接:http://codeforces.com/contest/1105/problem/C
题目大意:给你n,l,r。每一个数都是在l,r范围之内,然后问你这n个数形成的序列能够被3整除。
具体思路:我们先计算出l,r区间内整除3之后是0的个数,是1的个数,是2的个数,然后我们从第一位循环到第n位,第i位之前余数是0的情况等于前一位余数是1的情况*(l到r区间内余数是2的情况)+前一位余数是0的情况*(l到r区间内余数是0的情况)+前一位余数是2的情况*(l到r区间内余数是1的情况)。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 const int maxn = 2e5+100; 5 const int mod = 1e9+7; 6 ll dp[maxn][3]; 7 int main(){ 8 ll n,l,r; 9 scanf("%lld %lld %lld",&n,&l,&r); 10 ll a0,a1,a2; 11 a0=r/3-(l-1)/3; 12 a1=(r+1)/3-(l-1+1)/3; 13 a2=(r+2)/3-(l-1+2)/3; 14 dp[0][0]=1; 15 for(int i=1;i<=n;i++){ 16 dp[i][0]=(dp[i-1][0]*a0%mod+dp[i-1][1]*a2%mod+dp[i-1][2]*a1%mod)%mod; 17 dp[i][1]=(dp[i-1][0]*a1%mod+dp[i-1][1]*a0%mod+dp[i-1][2]*a2%mod)%mod; 18 dp[i][2]=(dp[i-1][0]*a2%mod+dp[i-1][1]*a1%mod+dp[i-1][2]*a0%mod)%mod; 19 } 20 printf("%lld\n",dp[n][0]); 21 return 0; 22 }