zoukankan      html  css  js  c++  java
  • 碎碎念(DP)

    链接:https://ac.nowcoder.com/acm/contest/3006/F
    来源:牛客网

    题目描述


    在ACM比赛里,除了CE以外都是有效的提交。每一个提交都会有其评测的结果,或是AC,或是RJ(Rejected,包含各种不通过的情况)。

    往往一个人上去提交的时候,总有一个队友会坐在边上等着结果。那个人,往往都是只读题不写题的云选手~

    牛牛战队里也有这样的云选手——牛能。当牛能看到有效提交得到了AC以后,都会大呼一声“你好能啊!”。

    反之,如果得到了RJ的话,就会化身为喷子,说xxx句“你能不能行啊!”。大家比赛的都十分紧张,这样的大声呼喊未免会引起旁边队伍的注意。

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

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

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

    “啊……我也记不清了,大概是在[L,R]这个区间吧”

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

    输入描述:

    输入数据包括单组数据、多组询问。输入第一行包含一个整数x(2≤x≤100000),表示牛能在RJ状态下会说“你能不能行啊!”的句子数量。

    第二行包括一个整数Q(1≤Q≤105),表示询问数量。

    接下来Q行,每行包括两个整数L,R(1≤L≤R≤100000),表示每次询问下句子的区间数。

    输出描述:

    对于每组数据,在一行内输出一个整数,表示牛牛战队提交结果的可能性。由于结果可能很大,请对1000000007取模。

    输入

    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,但是因为提交顺序的不同,视为不同种类。

    考虑到了第i句话时候,这种状态都可能由两种状态转移而来。

    构造dp[ i ][ 0/1 ]。

    dp[ i ][ 0 ]表示共说了i句话,并且最后一发AC了的方案数。

    dp[ i ][ 1 ]表示共说了i句话,并且最后一发RJ了的方案数。

    由此可知转移条件

    dp[ i ][ 0 ]=dp[ i-1 ][ 0 ]+dp[ i-1 ][ 1 ](前面一发是WA是AC无关紧要)

    dp[ i ][ 1 ]=dp[ i-k ][ 0 ](前面一发只能是AC)

    易确定边界条件 dp[ 0 ][ 0 ]=1; dp[ 0 ][ 1 ]=0;

    有Q次区间查询,查询数目较多,我们可以线性时间内预处理成前缀和ans[i]。
    查询区间[L,R]时,输出ans[R]-ans[L-1]即可。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <stack>
     9 #include <queue>
    10 #include <set>
    11 #include <map>
    12 #include <sstream>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const double eps =1e-8;
    16 const int mod=1e9+7;
    17 const int maxn=1e5+10;
    18 using namespace std;
    19 
    20 LL dp[maxn][2];//0表示最后一发AC,1表示最后一发RJ 
    21 LL ans[maxn];
    22 
    23 int main()
    24 {
    25     #ifdef DEBUG
    26     freopen("sample.txt","r",stdin);
    27     #endif
    28     
    29     int n,m; 
    30     scanf("%d %d",&n,&m);
    31     dp[0][0]=1;//边界 
    32     for(int i=1;i<maxn;i++)//预处理 
    33     {
    34         dp[i][0]=(dp[i-1][0]+dp[i-1][1])%mod;
    35         if(i>=n) dp[i][1]=dp[i-n][0];
    36         ans[i]=(ans[i-1]+(dp[i][0]+dp[i][1])%mod)%mod;//前缀和 
    37     }
    38     while(m--)//m次查询 
    39     {
    40         int L,R;
    41         scanf("%d %d",&L,&R);
    42         printf("%lld
    ",(ans[R]-ans[L-1]+mod)%mod);
    43     }
    44     
    45     return 0;
    46 }

    -

  • 相关阅读:
    红帽考试学习第六记
    红帽考试学习第五记
    红帽考试学习第四记
    红帽考试学习第三记
    C++ 学习笔记之---类和动态内存分配
    C++ 学习笔记之---类的自动转换
    C++ 学习笔记之---对象和类
    指针与引用的区别
    年轻人,往哪里走?
    最近感兴趣的东西
  • 原文地址:https://www.cnblogs.com/jiamian/p/12310505.html
Copyright © 2011-2022 走看看