DP 一道遞推題。。。

2022-06-18 06:33:11 字數 1569 閱讀 7674

bob想要構造一張由n個節點構成的圖。構造的過程由兩步組成:首先bob會取出n個孤立的點,並把它們從1到n編號,然後對每個節點用一種顏色染色,bob一共可以使用k種不同的顏色。接下來bob會在這張圖中加入一些有向邊,對於每乙個編號範圍在[2,n]的節點i,bob有可能選擇乙個節點j滿足j < i並且節點i與j的顏色不同,然後加入一條從i到j的有向邊,對於節點i,bob也有可能不加任何的有向邊。現在你需要回答bob有可能構造出多少種不同的圖。

輸入:

第一行包含三個整數n,k。

輸出:

輸出乙個整數佔一行,表示對應的答案模10^9 + 7。

樣例輸入:

3 2樣例輸出:

24(所有的24種可能情況如下)

資料範圍:

對於20%的資料,1 <= n <= 5,1 <= k <= 2。

對於100%的資料,1 <= n <= 10^6,1 <= k <= 10^6。

看到題被嚇尿了,感覺根本沒法做,寫了個暴搜,結果全錯+t了。。。

這個題比較考思維,其實要往遞推方向想。我們假設dp[i]表示有i個點時所能夠畫出來的所有組合,那麼我們來分析一下是結果是如何遞推的。

dp[i]無非由兩部分組成,一部分是不連線的,一部分是連線的,對於不連線的,很簡單,只需要dp[i-1]*k就行了,無需多說。

那麼連線的部分怎麼辦呢?我們可以連向前i-1個點,但是我們並不知道它們的具體顏色,但是我們只要保證連著的兩個顏色不一樣即可,那麼對於第i個點往前連的時候,它能連的顏色只有(k-1)種,然後分步原理,再乘上i-1的組合總數就行了,所以連線的部分轉移方程是(i-1)*(k-1)*dp[i-1]。所以總的狀態轉移方程是dp[i]=dp[i-1]*k+(i-1)*(k-1)*dp[i-1]。。。不仔細想真想不出來啊。。。

那麼**如下:

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;

7const

long

long mod=1000000007;8

const

int maxn=1000000+10;9

void

init()

1017

long

long

n,k;

18long

long dp[maxn];//

i個節點,k種顏色,所有可能的組合總數

19void

read()

2023

void

work()

2430 printf("

%i64d

",dp[n]);31}

32int

main()

33

一道簡單DP題

首先,一看就應該知道這是一道dp題。原因在於其當前結果都依賴於前面計算得到的子結果。區分分治和dp的關鍵條件就在於演算法執行中間階段的計算結果是否依賴於其子問題的結果,若依賴則為dp,否則為分治。dp題的關鍵在於找出狀態轉移方程和初始條件 或者稱為邊界值 找出狀態轉移方程的關鍵又在於找對乙個狀態函式...

記一道DP題

給定 n l r 求長度為n的 且元素在 l r 的 且 陣列元素和是3的倍數的 陣列的 個數 dpmod0 表示區間內的數mod 3 0的個數 mod1 mod2 同理 dp i j 表示 長度為i的 陣列元素mod 3 為 j 的陣列的個數 如果 i 1長度的陣列和 mod 3 0 那麼我再加乙...

樹形dp 的 一道巨簡單題

這三個字寫這麼大完全是為了提醒自己 hhhh 竟然這都不會 樹形dp 不懂得如何推出狀態表示式 即使再簡單 看見題目就無從下手!有點煩 所以決定多刷一點dp題,先看了最基礎的 洛谷p1352 這個題其實挺簡單的,但是我是真的廢。題意 給出一棵樹,每個節點有自己的權值,選擇出一些點,選擇點的時候如果選...