計數類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 每...