動態規劃篇(1)
第一篇模板是動態規劃的樹形dp;
題目為「沒有上司的舞會」,詳情參考演算法競賽高階。
dp注意重要陣列f,f[i][0]表示不參加,f【i】表示參加;
#include
#include
#include
using
namespace std;
const
int mn=
10010
;int n;
int h[mn]
;bool v[mn]
;int f[mn][3
]; vector<
int>q[mn]
;void
dfs(
int x)
}int
main()
int x,y;
for(
int i=
1;i<=n;i++
)int root;
for(
int i=
1;i<=n;i++)}
dfs(root)
;int ans=0;
ans=
max(f[root][0
],f[root][1
]); cout<}
第二篇是揹包類樹形dp
詳情參考「選課」;
f【i】【j】表示以i為跟的子樹中選j門課所能獲得最大學分
#include
#include
#include
using
namespace std;
const
int mn=
10010
;int n,m;
vector<
int>q[mn]
;int s[mn]
;//分數
int f[
500]
[500];
void
dfs(
int x)
if(x!=0)
//如果不為根節點
}int
main()
//以0為虛擬根節點
dfs(0)
; cout<[m];
}
第三篇是區間dp模板。
題目為「石子合併」,詳情參考演算法競賽高階指南。
以下為核心**,i為區間長度,從2開始列舉,f【l】【r】表示從l到r區間合併的最小值。
for
(int i=
2;i<=n;i++
) f[l]
[r]+
=sum[r]
-sum[l-1]
;}}
動態規劃習題整理(1)
狀態表示 f i 表示以第 i 個元素結尾的所有連續子陣列的最大值。狀態轉移 f i max f i 1 0 nums i f i 可劃分為兩部分,以第 i 1個元素結尾的所有連續子陣列加上第i個元素,或者只選用第 i 個元素。答案為所有f i 中的最大值。優化 由於f i 在計算時只會用到f i ...
動態規劃整理(二)
題目描述 給定乙個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。注意 每個陣列中的元素不會超過 100 陣列的大小不會超過 200 分析 自頂向下分析 我們先得到一半的值是多少 在進行填充 與01 揹包不同的是 不受權重影響,但卻必須得填滿揹包 從 n個數字裡取...
動態規劃學習整理
目錄怎麼dp 遞迴 有記憶的遞迴 自上而下記憶法 自下而上填表法的區別 揹包類問題的求解誤區 在學動態規劃思想之前求解裝包類問題時,很容易想到根據價效比排序優先裝高價效比物品的貪心演算法,這就有點像線性規劃,連續型變數我們可以通過求導來計算,但涉及到整型就會很頭疼了 想要舉反例很簡單,比如只有兩個物...