A 小D的劇場 牛客練習賽40 dp

2021-09-11 02:24:59 字數 1578 閱讀 9967

題目的意思就是長度為n的序列,每個位置可以選擇1~49的數字,但是連續的3個不能出現他不喜歡的三和弦所有排列,問有多少種滿足條件的序列。

由於n很小使用dp求解,記錄當前位置和上一位使用了哪些數字,複雜度o(49^3*n)

d[i][j][k]表示長度為i的序列最後一位為k倒數第二位為j的情況數量,在轉移時遍歷當前位和前兩位所用數值進行轉移。

轉移方程d[l][j][k] = d[l][j][k] + d[l - 1][i][j],l表示長度ijk為後三位,轉移時候注意判斷ijk所組成的三和弦是否滿足條件。

#include

#include

#define fst first

#define sed second

using namespace std;

typedef

long

long ll;

const

int inf =

0x3f3f3f3f

;const ll linf =

0x3f3f3f3f3f3f3f3f

;const

int mod =

1e9+7;

const

int maxn =

5e2+10;

const

int maxm =50;

ll d[maxn]

[maxm]

[maxm]

;//d[i][j][k]表示長度為i當前位用k上一位用j的方案數量

bool x[maxm]

[maxm]

[maxm]

;//非法狀態

intmain()

d[0][

0][0

]=1;

for(

int l =

1; l <= n; l++

)for

(int i =

0; i <

50; i++

)//列舉連續三位

for(

int j =

0; j <

50; j++

)for

(int k =

1; k <

50; k++

)//新的位置只能從1開始if(

!x[i]

[j][k]

)//不是非法狀態

d[l]

[j][k]

=(d[l]

[j][k]

+ d[l -1]

[i][j]

)% mod;

ll ans =0;

for(

int j =

1; j <

50; j++

)for

(int k =

1; k <

50; k++

) ans =

(ans + d[n]

[j][k]

)% mod;

cout << ans << endl;

return0;

}

牛客練習賽40

題目鏈結 c題 小a與尤拉路 先考慮迴路的情況。由於是一棵樹,任兩點間路徑只有一條,從一條邊走到深度更大的點,一定還會從同一條邊返回以回到起點或者遍歷其他子樹,所以每條邊需要複製一次,此時答案是邊權和的兩倍。不是迴路的情況可以減掉從終點回到起點的路徑,要讓這條路徑盡量長,所以長度一定是直徑的長度。答...

牛客練習賽58 D 迷宮 dp

考慮到無論往左走還是往下走,下一步又會回來,進而不斷在兩個格仔間來回跳,所以只能往右走或者往下走,並且優先往右走 設 f i j 表示走到 i,j 的最小操作次數,考慮轉移 begin f i j to f i j 1 f i j s i j 1 0 to f i 1 j end 暴力轉移即可 我個...

牛客練習賽40 題解(部分)

官方題解 a 小d的劇場 大概意思就是,有1 49個數,代表著不同的音符,問你能組成長度為n的串有多少種 mod 109 7 有若干個限制,比如1 2 3,就是1,2,3不能放在一起,然後問你在這些限制下有多少種不同的長度為n的串。3 n 500,0 q 117649,1 a,b,c 49 思路 看...