C - Ayoub and Lost Array(簡單DP)

題目鏈接http://codeforces.com/contest/1105/problem/C

題意:有一個數組,元素個數n,元素的最小值l,元素的最大值r,另外數組元素和可整除3,問:有多少種這樣的數組?(註明: [1,2],[2,1]這兩個屬於不同的數組)輸出的結果(10e9+7)取模。

數據範圍:( 1≤n≤2*10^5,1≤l≤r≤10^9)

思路:這種類型的題目,要麼是找到公式求解,要麼是採用DP求解。

DP數組:dp[n][3]   

dp[i][0]表示 該數組元素個數爲i,元素和對3取模爲0,這種的數組有dp[i][0]種;

dp[i][1]表示 該數組元素個數爲i,元素和對3取模爲1,這種的數組有dp[i][1]種;

dp[i][2]表示 該數組元素個數爲i,元素和對3取模爲2,這種的數組有dp[i][2]種;

元素和可整除3,元素對3取模結果有:0,1,2;

我們先算出從l到r數據範圍中取模結果爲0,1,2的個數,設爲:a0,a1,a2;

當前的狀態與前一個的狀態有關--->寫成狀態轉移方程

dp[i][0]=dp[i-1][0]*a+dp[i-1][1]*a2+dp[i-1][2]*a1;

dp[i][1]=dp[i-1][0]*a1+dp[i-1][1]*a0+dp[i-1][2]*a2;

dp[i][2]=dp[i-1][0]*a+dp[i-1][1]*a2+dp[i-1][2]*a1;

現在還有一個問題:就是餘0,1,2的個數a0,a1,a2的求法?

a0 = r / 3 - (l - 1) / 3;
a2 = (r + 2) / 3 - (l + 1) / 3;
a1 = (r + 1) / 3 - l / 3;

代碼:

#include<bits/stdc++.h>

using namespace std;
//簡單DP
#define maxn 200010
#define ll long long
const int mod = 1e9 + 7;
int n, l, r;
long long dp[maxn][3];

int main() {
    cin >> n >> l >> r;
    ll a0, a1, a2;//分別表示l到r這些數中餘0,餘1,餘2的數
    a0 = r / 3 - (l - 1) / 3;
    a2 = (r + 2) / 3 - (l + 1) / 3;
    a1 = (r + 1) / 3 - l / 3;
    dp[0][0] = 1;
    for (int i = 1; i <= n; i++) {
        dp[i][0] = ((dp[i - 1][0] * a0) % mod + (dp[i - 1][1] * a2) % mod + (dp[i - 1][2] * a1) % mod) % mod;
        dp[i][1] = ((dp[i - 1][0] * a1) % mod + (dp[i - 1][1] * a0) % mod + (dp[i - 1][2] * a2) % mod) % mod;
        dp[i][2] = ((dp[i - 1][0] * a2) % mod + (dp[i - 1][1] * a1) % mod + (dp[i - 1][2] * a0) % mod) % mod;
    }
    cout << dp[n][0] << endl;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章