• C. Ayoub and Lost Array cf dp


    C. Ayoub and Lost Array
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Ayoub had an array aa of integers of size nn and this array had two interesting properties:

    • All the integers in the array were between ll and rr (inclusive).
    • The sum of all the elements was divisible by 33 .

    Unfortunately, Ayoub has lost his array, but he remembers the size of the array nn and the numbers ll and rr , so he asked you to find the number of ways to restore the array.

    Since the answer could be very large, print it modulo 109+7109+7 (i.e. the remainder when dividing by 109+7109+7 ). In case there are no satisfying arrays (Ayoub has a wrong memory), print 00 .

    Input

    The first and only line contains three integers nn , ll and rr (1n2105,1lr1091≤n≤2⋅105,1≤l≤r≤109 ) — the size of the lost array and the range of numbers in the array.

    Output

    Print the remainder when dividing by 109+7109+7 the number of ways to restore the array.

    Examples
    Input
    Copy
    2 1 3
    
    Output
    Copy
    3
    
    Input
    Copy
    3 2 2
    
    Output
    Copy
    1
    
    Input
    Copy
    9 9 99
    
    Output
    Copy
    711426616
    
    Note

    In the first example, the possible arrays are : [1,2],[2,1],[3,3][1,2],[2,1],[3,3] .

    In the second example, the only possible array is [2,2,2][2,2,2] .

    这个题目先要意识到这是一个动态规划

    他是在范围内取一个元素个数为n,对3的余数为0的集合的方案数。

    这个就可以当初一种动态规划,从1到n转移。

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+100;
    ll mod=1e9+7,dp[maxn][4];//dp[i][j]代表余数为j时,集合元素为i的方案数
    
    int main()
    {
        int n,l,r,a=0,b=0,c=0;
        cin>>n>>l>>r;
        int k=(r-l)/3;
        a=b=c=k;
        for(int i=l+3*k;i<=r;i++)
        {
            if(i%3==0) a++;
            if(i%3==1) b++;
            if(i%3==2) c++;
        }
        dp[1][0]=a;
        dp[1][1]=b;
        dp[1][2]=c;
        for(int i=2;i<=n;i++)
        {
            dp[i][0]=dp[i-1][0]*a%mod;
            dp[i][0]%=mod;
            dp[i][0]+=dp[i-1][1]*c%mod;
            dp[i][0]%=mod;
            dp[i][0]+=dp[i-1][2]*b%mod;
            dp[i][0]%=mod;
            dp[i][1]=dp[i-1][0]*b%mod;
            dp[i][1]%=mod;
            dp[i][1]+=dp[i-1][1]*a%mod;
            dp[i][1]%=mod;
            dp[i][1]+=dp[i-1][2]*c%mod;
            dp[i][1]%=mod;
            dp[i][2]=dp[i-1][0]*c%mod;
            dp[i][2]%=mod;
            dp[i][2]+=dp[i-1][1]*b%mod;
            dp[i][2]%=mod;
            dp[i][2]+=dp[i-1][2]*a%mod;
            dp[i][2]%=mod;
        }
        cout<<dp[n][0]<<endl;
        return 0;
    }

     

  • 相关阅读:
    远程线程注入与CreateRemoteThread
    游戏修改器编写原理
    软件保护技术常见保护技巧
    反跟踪技术
    C++用static声明的函数和变量小结
    PE文件格式分析及修改
    MMX指令集在C++中的使用
    HOOKAPI之修改IAT法则
    如何获取 程序加载后的内存起始地址
    Java线程中断的本质和编程原则
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/10357249.html
Copyright © 2020-2023  润新知