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\n", DP[N][0]);
}

int main()
{
    //freopen("input.txt", "r", stdin);
    scanf("%d %d %d", &N, &L, &R);
    solve();
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/dybala21/p/10319282.html