CodeForces - 1105C (dp)

这道题是一道dp题,给出数组的个数n,上下边界l和r(包括l,r),要求满足所有数组中元素之和满足被3整除的情况有多少种,

我们可以知道l到r中被3整除的数有mod0个,被3整除余1的有mod1个,被3整除余2的有mod2个。

dp[i][j]表示数组中前i个数的和被3整除余j的个数,我们要求的就是dp[n][0];

dp[i][0]=dp[i][0]*mod0+dp[i][1]*mod2+dp[i][2]*mod1,依次类推

 1 #include<iostream>
 2 #include<string.h>
 3 #include<string>
 4 #include<sstream>
 5 #include<vector>
 6 #include<deque>
 7 #include<map>
 8 #include<algorithm>
 9 #include<iomanip>
10 #include<math.h>
11 #include<set>
12 using namespace std;
13 
14 int mod = 1000000007;
15 typedef long long ll;
16 typedef unsigned long long ull;
17 ll dp[200005][3];
18 
19 int main()
20 {
21     ll n,l,r;
22     while (cin >> n >> l >> r)
23     {
24         
25         ll mod0 = r/3-l/3;
26         if (l % 3 == 0)
27             mod0+=1;
28         ll mod1 = (r + 2) / 3 - (l + 2) / 3;
29         if ((l + 2) % 3 == 0)
30             mod1 += 1;
31         ll mod2 = r-l+1-mod0-mod1;
32         memset(dp, 0, sizeof(0));
33         dp[1][0] = mod0;
34         dp[1][1] = mod1;
35         dp[1][2] = mod2;
36         for (int i = 2; i <= n; i++)
37         {
38             dp[i][0] = (dp[i - 1][0] * mod0 + dp[i - 1][1] * mod2 + dp[i - 1][2] * mod1)%mod;
39             dp[i][1] = (dp[i - 1][0] * mod1 + dp[i - 1][1] * mod0 + dp[i - 1][2] * mod2) % mod;
40             dp[i][2]= (dp[i - 1][0] * mod2 + dp[i - 1][1] * mod1 + dp[i - 1][2] * mod0) % mod;
41         }
42         cout << dp[n][0] % mod << endl;
43     }
44     return 0;
45 }

 

posted on 2019-03-06 19:13  QingFengDaHui  阅读(101)  评论(0编辑  收藏  举报

导航