题面:

传送门

题目描述:

题意很简单:1.数组中的所有整数都在区间[l, r],2.所有元素之和能被3整除。现在知道这个数组的大小,l和r,问:按照题目的要求组成的数组一共有多少种可能。
 

题目分析:

这道题应该是一道常见的用dp来解决计数的问题。
1.如果忽略所有元素之和能被3整除,那么,按照正常的想法答案肯定是:(r-l+1)n。但是题目多了所有元素之和能被3整除,看似难度大了很多。其实,我们可以分析一下:忽略所有元素之和能被3整除,答案是怎样想出来的:每一个“位”上都有(r-l+1)种选择,然后把每个“位”上的选择乘起来,就是(r-l+1)n。因此,我们可以通过研究每个"位"上的选择来解决这个问题。但在实际情况中,这个“位”的选择实在是不好解决:要确定所有元素之和要被3整除,有些“位”可能是之前不能被3整除,经过几次累加后就能被3整除了,情况过于复杂。这时,我们要想一种能“简化过程”的思想:
把问题拆解子问题,对应的解决办法其中就有dp。我们可以这样定义问题:前n个数的和能被3模余p(p = 0, 1, 2)的可能有多少?那么其中一个子问题是:前n-1个数的和能被3模余p(p = 0, 1, 2)的可能有多少?换成更直观的图,其实就是:
前n-1位已经确定好(计算出前n-1位的可能数),如果确定了第n位的选择,那么根据组合数学计数原理,就可以用前n-1位计算出的结果计算出前n位一共有多少种选择。第n位的选择要看当前的“状态”是什么:也就是和p有关。
 
2.经过分析,有如下选择(这里用dp[p][n]来代表上面的含义):
当p == 0时:
dp[0][n] += dp[0][n-1] * (第n位选被3模后余数为0的数的个数)
dp[0][n] += dp[1][n-1] * (第n位选被3模后余数为2的数的个数)
dp[0][n] += dp[2][n-1] * (第n位选被3模后余数为1的数的个数)
 
当p == 1时:
dp[0][n] += dp[0][n-1] * (第n位选被3模后余数为1的数的个数)
dp[0][n] += dp[1][n-1] * (第n位选被3模后余数为0的数的个数)
dp[0][n] += dp[2][n-1] * (第n位选被3模后余数为2的数的个数)
 
当p == 2时:
dp[0][n] += dp[0][n-1] * (第n位选被3模后余数为2的数的个数)
dp[0][n] += dp[1][n-1] * (第n位选被3模后余数为1的数的个数)
dp[0][n] += dp[2][n-1] * (第n位选被3模后余数为0的数的个数)
我们先看看当p == 0时,是怎样得到结果的:有三种情况:第一种情况:前n-1个数的和取模后余数为0且第n个数选余数为0的数,这样才能保证前n位之和取模后余数为0(也就是p);第二种情况:前n-1个数的和取模后余数为1且第n个数选余数为2的数,这样才能保证前n位之和取模后余数为0(也就是p);第三种情况同理可得,p == 1和p == 2也同理可得。
 
3.现在的问题关键是:第n位选被3模后余数为p的数的个数怎么算:我们可以思考这样一个问题:1-x中,被3取模后余数为p的数的个数 fp(x) 是多少?假如我们解决这个问题,就可以用 fp(r) - fp(l-1) 来算出答案了。因为p的选择不多(p = 0, 1, 2),所以我们直接分类讨论就行了:
1-x中,被3取模后余数为0的数的个数:f0(x) = x / 3
1-x中,被3取模后余数为1的数的个数:f1(x) = (x + 2) / 3
1-x中,被3取模后余数为2的数的个数:f2(x) = (x + 1) / 3
 
4.自己注意初始化问题。
 
 
AC代码:
 1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <cmath>
5 #include <algorithm>
6 using namespace std;
7 const long long mod = 1e9+7;
8 const long long maxn = 2e5+5;
9 long long n, l, r;
10
11 long long dp[5][maxn];
12
13 const int yu[3][3] = {{0, 2, 1}, {1, 0, 2}, {2, 1, 0}};
14
15
16 int main(){
17 cin >> n >> l >> r;
18 int t;
19
20 //注意初始化
21 for(int i = 0; i < 3; i++){
22 t = (3-i)%3;
23 dp[i][1] = ( (r+t)/3-(l+t-1)/3 );
24 }
25
26
27 for(int i = 2; i <= n; i++){
28 for(int k = 0; k < 3; k++){
29 for(int p = 0; p < 3; p++){
30 t = (3-yu[k][p]) % 3;
31 dp[k][i] += dp[p][i-1]*( (r+t)/3-(l+t-1)/3 ) % mod;
32 dp[k][i] %= mod;
33 }
34 }
35 }
36
37 cout << dp[0][n] << endl;
38
39 return 0;
40 }
 
 
 
 

Codeforces Round #533 C. Ayoub and Lost Array的更多相关文章

  1. Codeforces Round #533 (Div. 2)题解

    link orz olinr AK Codeforces Round #533 (Div. 2) 中文水平和英文水平都太渣..翻译不准确见谅 T1.给定n<=1000个整数,你需要钦定一个值t, ...

  2. Codeforces Round #533 (Div. 2) C. Ayoub and Lost Array 【dp】

    传送门:http://codeforces.com/contest/1105/problem/C C. Ayoub and Lost Array time limit per test 1 secon ...

  3. Codeforces Round #533 (Div. 2) C.思维dp D. 多源BFS

    题目链接:https://codeforces.com/contest/1105 C. Ayoub and Lost Array 题目大意:一个长度为n的数组,数组的元素都在[L,R]之间,并且数组全 ...

  4. Codeforces Round #533 (Div. 2) Solution

    A. Salem and Sticks 签. #include <bits/stdc++.h> using namespace std; #define N 1010 int n, a[N ...

  5. Codeforces Round #533(Div. 2) C.Ayoub and Lost Array

    链接:https://codeforces.com/contest/1105/problem/C 题意: 给n,l,r. 一个n长的数组每个位置可以填区间l-r的值. 有多少种填法,使得数组每个位置相 ...

  6. Codeforces Round #533 (Div. 2) C. Ayoub and Lost Array(递推)

    题意: 长为 n,由 l ~ r 中的数组成,其和模 3 为 0 的数组数目. 思路: dp[ i ][ j ] 为长为 i,模 3 为 j 的数组数目. #include <bits/stdc ...

  7. Codeforces Round #258 (Div. 2) . Sort the Array 贪心

    B. Sort the Array 题目连接: http://codeforces.com/contest/451/problem/B Description Being a programmer, ...

  8. Codeforces Round #555 (Div. 3) E. Minimum Array 【数据结构 + 贪心】

    一 题面 E. Minimum Array 二 分析 注意前提条件:$0 \le  a_{i} \lt n$ 并且 $0 \le  b_{i} \lt n$.那么,我们可以在$a_{i}$中任取一个数 ...

  9. Codeforces Round #533 (Div. 2) B. Zuhair and Strings 【模拟】

    传送门:http://codeforces.com/contest/1105/problem/B B. Zuhair and Strings time limit per test 1 second ...

随机推荐

  1. Redis 主从复制(Replication)

    为了保证服务的可用性,现代数据库都提供了复制功能,同时在多个进程中维护一致的数据状态. Redis 支持一主多从的复制架构,该功能被简化成了一条 SLAVEOF 命令,下面通过条命令来解析 Redis ...

  2. UML类图设计神器 AmaterasUML 的配置及使用

    最近写论文需要用到UML类图,但是自己画又太复杂,干脆找了个插件,是Eclipse的,也有IDEA的,在这里我简单说下Eclipse的插件AmaterasUML 的配置与使用吧. 点击这里下载Amat ...

  3. Leetcode(213)-打家劫舍II

    你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金.这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的.同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在 ...

  4. Python+OpenCV+图片旋转并用原底色填充新四角

    import cv2 from math import fabs, sin, cos, radians import numpy as np from scipy.stats import mode ...

  5. play games for learning web skills

    play games for learning web skills CSS flexbox https://codepip.com/games/flexbox-froggy/ CSS grid ht ...

  6. jest & code testing

    jest jest & code testing https://jestjs.io/zh-Hans/ 24.9 https://jestjs.io/docs/zh-Hans/getting- ...

  7. SVG image tag

    SVG image tag https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/SVG_Image_Tag <?xml versi ...

  8. 微前端 & 微前端实践 & 微前端教程

    微前端 & 微前端实践 & 微前端教程 微前端 micro frontends https://micro-frontends.org/ https://github.com/neul ...

  9. TYLER ADAMS BRADBERRY:人到中年,要学会戒掉这三点

    在一些国家的一些人当中,总会出现这样一个问题"中年危机".而到了中年,人与人间的差距似乎也变得越来越大.有人说,人到中年,是一个门槛,有的人迈过去了,有的人没迈过去.但是,其实实话 ...

  10. 「NGK每日快讯」2021.1.7日NGK第65期官方快讯!