题面:

传送门

题目描述:

题意很简单: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. C++ new delete malloc free

    title: C++ new delete malloc free date: 2020-03-10 categories: c++ tags: 语法 C++的new delete malloc fr ...

  2. 云原生系列2 部署你的第一个k8s应用

    云原生的概念和理论体系非常的完备,but talk is cheap , show me the code ! 但是作为一名程序员,能动手的咱绝对不多BB,虽然talk并不cheap , 能跟不同层次 ...

  3. vue 如何重绘父组件,当子组件的宽度变化时候

    vue 如何重绘父组件,当子组件的宽度变化时候 vue & dynamic el-popover position demo https://codepen.io/xgqfrms/pen/wv ...

  4. React 性能优化 All In One

    React 性能优化 All In One Use CSS Variables instead of React Context https://epicreact.dev/css-variables ...

  5. SwiftUI All In One

    SwiftUI All In One SwiftUI SwiftUI is an innovative, exceptionally simple way to build user interfac ...

  6. TypeScript with React

    TypeScript with React # Make a new directory $ mkdir react-typescript # Change to this directory wit ...

  7. Linux shell create file methods

    Linux shell create file methods touch, cat, echo, EOF touch $ touch file.py $ touch file1.txt file2. ...

  8. js 裁剪图片

    js 裁剪图片 https://gugeji.com/search?q=js剪切图片

  9. qt DateTime 计算时间

    qdatetime doc 获取当前时间 QDateTime t1 = QDateTime::currentDateTime(); qDebug() << t1.toString(&quo ...

  10. Renice INC:解密干型葡萄酒

    市场上,干型葡萄酒往往对比甜型葡萄酒(如甜红.甜白)受到更多葡萄酒爱好者的青睐.在葡萄酒界,大部分的红葡萄酒和白葡萄酒也都是干型的,而且它们的口感往往各有特色,并非千篇一律.今天,就跟随Renice ...