0
点赞
收藏
分享

微信扫一扫

2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】


​​题目传送门​​

题目描述

在ACM比赛里,除了CE以外都是有效的提交。每一个提交都会有其评测的结果,或是AC,或是RJ(Rejected,包含各种不通过的情况)。往往一个人上去提交的时候,总有一个队友会坐在边上等着结果。那个人,往往都是只读题不写题的云选手~

牛牛战队里也有这样的云选手——牛能。当牛能看到有效提交得到了AC以后,都会大呼一声“你好能啊!”,反之,如果得到了RJ的话,就会化身为喷子,说xx句“你能不能行啊!”。大家比赛的都十分紧张,这样的大声呼喊未免会引起旁边队伍的注意。

当然牛牛战队交题的时候也很小心,一旦这一发出现了RJ,下一发有效提交一定能获得AC。

比赛结束了以后,旁边的一支队伍愤怒的跑过来说:你们比赛的时候吵不吵啊,一直在这大吼,吼了这么多句!

激烈的争吵引起了吃瓜群众的注意,吃瓜群众问道:吼了多少句啊,这么讨厌的吗

“啊……我也记不清了,大概是在2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_acm比赛这个区间吧”

作为吃瓜群众的你,想根据这个信息算出,这个队伍有多少种有效提交结果序列的可能呢?

输入描述:

输入数据包括单组数据、多组询问。输入第一行包含一个整数2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_acm比赛_02,表示牛能在RJ状态下会说“你能不能行啊!”的句子数量。

第二行包括一个整数2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_数据_03,表示询问数量。

接下来2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_取模_04行,每行包括两个整数2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_acm比赛_05,表示每次询问下句子的区间数。

输出描述:

对于每组数据,在一行内输出一个整数,表示牛牛战队提交结果的可能性。由于结果可能很大,请对2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_acm比赛_06取模。

输入

3
3
3 3
1 4
1 5

输出

2
7
11

说明

第一组询问:可以是三个AC,或者一个RJ。
第二组询问:可以是1~4个AC,一个AC和一个RJ(共2种顺序),或者一个RJ。
第三组询问:可以有1~5个AC,两个AC和一个RJ(共3种顺序),一个AC和一个RJ(共2种顺序),或者一个RJ。

备注:

AC RJ AC AC 和 AC AC AC RJ 虽然都是3个AC,1个RJ,但是因为提交顺序的不同,视为不同种类。

题解

  • 很明显是动态规划求方案数的问题
  • 题意有点绕,其实就是说:2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_数据_07说一句,2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_取模_082020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_acm比赛_09句,给你2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_acm比赛_09后,询问说的话数在2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_取模_11区间内的说话方案数
  • 首先2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_acm比赛_12都只有一种方式:全都2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_数据_07
  • 对于2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_数据_14,有两种方式
  1. 2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_数据_15句话 +2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_acm比赛_16
  2. 2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_数据_17句话 +2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_数据_18
  • 由于查询范围较大,可以线性复杂度处理答案的前缀和,然后输出2020牛客寒假算法基础集训营5.F——碎碎念【DP & 前缀和】_acm比赛_19

AC-Code

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5;
const int mod = 1e9 + 7;

int dp[maxn + 7];
int main() {
int k, q; while (cin >> k >> q) {
dp[0] = 1, dp[k] = 2;
for (int i = 1; i < k; ++i) dp[i] = 1;
for (int i = k + 1; i <= maxn; ++i) dp[i] = (dp[i - 1] + dp[i - k - 1]) % mod;
for (int i = 1; i <= maxn; ++i) dp[i] = (dp[i] + dp[i - 1]) % mod;
while (q--) {
int l, r; cin >> l >> r;
cout << (dp[r] - dp[l - 1] + mod)%mod << endl;
}
}
}


举报

相关推荐

0 条评论