Ayoub and Lost Array
Codeforces Round #533 (Div. 2) - C. Ayoub and Lost Array
B站视频讲解 https://www.bilibili.com/video/av41282261
题意:
大小为
n
n
n 的数组,数据范围是
[
l
,
r
]
[l,r]
[l,r],所有数的和被3整除,求满足条件的数组不同的方法数,答案模
1
e
9
+
7
1e9+7
1e9+7。
思路:
线性dp。
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] 表示长度为
i
i
i 的数组,
%
3
=
j
\%3 = j
%3=j 的可能组合数。由前往后推,状态转移方程:
对dp[i][0]:%3=0加%3=0等于%3=0,%3=1加%3=2等于%3=0,%3=2加%3=1等于%3=0。同理dp[i][1],dp[i][2]
dp[i][0] = dp[i - 1][0] * cnt[0] + dp[i - 1][1] * cnt[2] + dp[i - 1][2] * cnt[1];
dp[i][1] = dp[i - 1][0] * cnt[1] + dp[i - 1][1] * cnt[0] + dp[i - 1][2] * cnt[2];
dp[i][2] = dp[i - 1][0] * cnt[2] + dp[i - 1][1] * cnt[1] + dp[i - 1][2] * cnt[0];
c n t [ i ] cnt[i] cnt[i] 是区间 [ l , r ] [l,r] [l,r]内 % 3 = i \%3=i %3=i 的数的个数。
Code:
/* codeforces 蓝桥6 D. Ayoub and Lost Array
我的链接 https://codeforces.com/group/HD13CEfWEl/contest/239779/problem/D
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
const ll mod = 1e9 + 7;
ll n, l, r;
ll dp[maxn][3];
// dp[i][j] 长度为 i 的数组,%3 == j 的可能组合数
// 答案:dp[n][0]
ll cnt[3];
int main() {
cin >> n >> l >> r;
cnt[0] = cnt[1] = cnt[2] = (r - l + 1) / 3; //取区间范围内3的最大整数倍,模3等于0、1、2的个数一样
ll le = (r - l + 1) % 3; //处理左边剩下的不够3的个数(1或2)
if (le == 1)
cnt[l % 3]++;
else if (le == 2) {
cnt[l % 3]++;
cnt[(l + 1) % 3]++;
}
//初始化
dp[1][0] = cnt[0] % mod;
dp[1][1] = cnt[1] % mod;
dp[1][2] = cnt[2] % mod;
for (int i = 2; i <= n; ++i) {
dp[i][0] = dp[i - 1][0] * cnt[0] + dp[i - 1][1] * cnt[2] + dp[i - 1][2] * cnt[1];
dp[i][1] = dp[i - 1][0] * cnt[1] + dp[i - 1][1] * cnt[0] + dp[i - 1][2] * cnt[2];
dp[i][2] = dp[i - 1][0] * cnt[2] + dp[i - 1][1] * cnt[1] + dp[i - 1][2] * cnt[0];
dp[i][0] %= mod;
dp[i][1] %= mod;
dp[i][2] %= mod;
}
cout << dp[n][0] << endl;
return 0;
}