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
",dp[n][0]);
21 return 0;
22 }
原文地址:https://www.cnblogs.com/letlifestop/p/10297000.html