• C. Ayoub and Lost Array Round #533 (Div. 2) 【DP】


    一、题面

    链接

    二、分析

    关于这题,两个点。

    第一个点,是需要能够分析出$[L,R]$区间的3的余数的个数。

    首先,可以得到,$[L,R]$区间内共有$(R-L+1)$个数。

    设定余数为0,1,2的为一组,那么1,2,0和2,0,1也是一组。那么可以肯定能得到$(R-L+1)/3$组。

    那么还余下了$(R-L+1)%3$个数。这里就需要考虑从$L$开始往右移$(R-L+1)%3$个数,分析这几个数的余数即可。因为这几个数后的数肯定是能分成3个一组的。

    第二个点,用DP的思维去求解。

    区间内的数能分成0,1,2三种情况。那么如果有N位数,我们可以从第一位开始,不断的去往后组合。这样就得到了递推式。

    求出最后DP[N][0]就是最终的结果。

    三、AC代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int MOD = 1e9+7;
    const int MAXN = 2e5;
    int N, L, R;
    long long DP[MAXN+3][3];
    
    void solve()
    {
        memset(DP, 0, sizeof(DP));
        int a, b, c;
        int temp = R-L+1;
        a = temp/3;
        b = temp/3;
        c = temp/3;
        temp%=3;
        
        for(int i = 0; i < temp; i++)
        {
            switch((L+i)%3)
            {
                case 0:a++;break;
                case 1:b++;break;
                case 2:c++;break;
            }
        }
    
        DP[0][0] = 1;
    
        for(int i = 1; i <= N; i++)
        {
            DP[i][0]= (DP[i-1][0]*a%MOD + DP[i-1][1]*c%MOD + DP[i-1][2]*b%MOD)%MOD;
            
            DP[i][1]= (DP[i-1][1]*a%MOD + DP[i-1][0]*b%MOD + DP[i-1][2]*c%MOD)%MOD;
    
            DP[i][2]= (DP[i-1][2]*a%MOD + DP[i-1][0]*c%MOD + DP[i-1][1]*b%MOD)%MOD;
        }
        printf("%I64d
    ", DP[N][0]);
    }
    
    int main()
    {
        //freopen("input.txt", "r", stdin);
        scanf("%d %d %d", &N, &L, &R);
        solve();
        return 0;
    }
    

      

  • 相关阅读:
    opacity兼容性以及存在问题处理
    删除节点方法要注意的区别
    java基础-常见面试题(一)
    第04次作业-树
    第03次作业-栈和队列
    第02次作业-线性表
    Data_Structure-绪论作业
    C语言第二次实验报告
    C语言第一实验报告
    mysql 查询优化
  • 原文地址:https://www.cnblogs.com/dybala21/p/10319282.html
Copyright © 2020-2023  润新知