動態規劃 計數類DP

2021-10-13 16:02:11 字數 1328 閱讀 5414

計數類dp狀態函式的值是集合中元素的個數

1. 例題:整數劃分

乙個正整數n可以表示成若干個正整數之和,形如:n=n1+n2+…+nk,其中n1≥n2≥…≥nk,k≥1。

我們將這樣的一種表示稱為正整數n的一種劃分。

現在給定乙個正整數n,請你求出n共有多少種不同的劃分方法。

輸入格式

共一行,包含乙個整數n。

輸出格式

共一行,包含乙個整數,表示總劃分數量。

由於答案可能很大,輸出結果請對109+7取模。

資料範圍

1≤n≤1000

輸入樣例:

5輸出樣例:

7解題思路:用完全揹包的類似思路

1)確定狀態函式:f[i][j] 表示從1~ i個數中選任意個數,和值為j的所有組合。f[i][j] = 集合中元素的個數。

2)確定狀態轉移方程:根據第i個數選擇的個數劃分集合,與完全揹包相同的優化後得f[i][j] = f[i-1][j] + f[i-1][j-i]最後專化為一維。

#include

#include

using

namespace std;

const

int n =

1010

, mod =

1e9+7;

int n;

int f[n]

;int

main()

解法二:根據乙個解中的最小數劃分集合

1)確定狀態函式:f[i][j] 表示j個數的和為i的集合的數量

2)確定狀態轉移方程:f[i][j] = f[i-1][j-1] + f[i-j][j]

把集合劃分為解的最小值大一1和解的最小值是1兩類,如果解的最小值是1,則此時j-1個數的和為i-1的集合的數量等於f[i][j]。如果解的最小值大於1,則此時把解的j個數全部減1就有f[i][j] = f[i-j][j]。

#include

#include

using

namespace std;

const

int n =

1010

, mod =

1e9+7;

int n;

int f[n]

[n];

intmain()

動態規劃 區間DP 計數類DP

acwing 282.石子合併 區間dp的特點是狀態表示的時候表示的是某乙個區間的情況 動態規劃模型分析 即 不管石子如何合併,最後一步的操作一定是將兩堆石子合併 把步驟回到倒數第一步。當在做最後一次操作時遍歷所有區間,將最後一步最小的情況記錄進f陣列裡 部分如下 全域性變數 const int n...

動態規劃(三) 區間DP, 計數類DP

設有 n 堆石子排成一排,其編號為 1,2,3,n 每堆石子有一定的質量,可以用乙個整數來描述,現在要將這 n 堆石子合併成為一堆。每次只能合併相鄰的兩堆,合併的代價為這兩堆石子的質量之和,合併後與這兩堆石子相鄰的石子將和新堆相鄰,合併時由於選擇的順序不同,合併的總代價也不相同。例如有 4 堆石子分...

動態規劃 dp

威威貓系列故事 打地鼠 威威貓最近不務正業,每天沉迷於遊戲 打地鼠 每當朋友們勸他別太著迷遊戲,應該好好工作的時候,他總是說,我是威威貓,貓打老鼠就是我的工作!無話可說.我們知道,打地鼠是一款經典小遊戲,規則很簡單 每隔乙個時間段就會從地下冒出乙隻或多隻地鼠,玩遊戲的人要做的就是打地鼠。假設 1 每...