動態規劃,dp

2021-07-27 19:24:59 字數 3257 閱讀 3889

線性動規區間動規樹形動規

區間動規

根據題目要求,全域性最優滿足區域性最優;

典型題例

加分二叉樹(洛谷1040)

題目介紹

題目描述

設乙個n 個節點的二叉樹t 的中序遍歷為(1,2,3,…,n),其中數字 1,2,3,…,n 為節點編號。

每個節點都有乙個分數(均為正整數),記第j 個節點的分數為dj。二叉樹t 及它的每個子樹都有 乙個加分,任意一棵子樹s(包括t 本身)的加分等於s 的左子樹的加分×s 的右子樹的加分+s的根的分數。 若某棵子樹為空,規定其加分為1。葉子的加分就是葉節點本身的分數,不考慮它的空子樹。

試求一棵符合中序遍歷為(1,2,3,…,n)且加分最高的二叉樹t。要求輸出t 的最高加分和前序遍歷。

輸入格式

第1 行:乙個整數n(n<30),為節點個數。

地2 行:n個用空格隔開的整數,為每個節點的分數(分數<100)。

輸出格式

第1 行:乙個整數,為最高加分(結果不會超過4,000,000,000)。

第2 行:n個用空格隔開的整數,為該樹的前序遍歷。

輸入樣例

5 5 7 1 2 10

輸出樣例

145

3 1 2 4 5

題目分析

由於是中序遍歷,因此永遠滿足左子樹節點編號《根節點編號《右子樹節點編號,雖是樹形,但不存在選擇與決策問題,因此不是樹規;

在全域性最優的同時,區間最優同時滿足,因此選用區間dp;

動態轉移方程

f[r,l]=max

#include

#include

using

namespace

std;

int a[20][20],r[20][20];//r陣列儲存區間根節點

int n;

void find(int x,int y)//前序遍歷,dfs順序

return;

}int main()//區間dp,區域性最優滿足全域性最優,當前決策具有後效性

for(int i=n;i>=1;i--)//a[i][j]列舉的是從i到j的頂點;

for(int j=1+i;j<=n;j++)//列舉區間首,尾

for(int k=i;k<=j;k++)

}printf("%d",a[1][n]);//輸出的是從1~n的區間最大值;

}

線性動規

典型題例

飛彈攔截,合唱隊形;

以下是最長上公升子串行最長下降子串行模板

#include

#include

using

namespace

std;

int a[10001],b[10001],c[10001];

int main()

n--;

for(int i=1;i<=n;i++)

scanf("%d",&a[i]);

for(int i=1;i<=n;i++)//最長上公升

for(int i=n;i>=1;i--)//最長下降

if(mineprintf("%d%d",maxn,mine);

return

0;}

二分優化的最長上公升子串行

#include

#include

using

namespace

std;

int n,top,a[100005],t;

int main()

a[low]=t;

}} printf("%d",top);

}

樹狀動規

沒有上司的晚會

題目介紹

有個公司要舉行一場晚會。

為了能玩得開心,公司領導決定:如果邀請了某個人,那麼一定不會邀請他的上司

(上司的上司,上司的上司的上司……都可以邀請)。

每個參加晚會的人都能為晚會增添一些氣氛,求乙個邀請方案,使氣氛值的和最大。

input

第1行乙個整數n(1<=n<=6000)表示公司的人數。

接下來n行每行乙個整數。第i行的數表示第i個人的氣氛值x(-128<=x<=127)。

接下來每行兩個整數l,k。表示第k個人是第l個人的上司。

輸入以0 0結束。

output

乙個數,最大的氣氛值和。

input:

7 1

1 1

1 1

1 1

1 3

2 3

6 4

7 4

4 5

3 5

0 0output:

5思路分析

本題滿足樹的特徵,即有向無環,可以有多個後繼,但只能有乙個前驅,

最優化問題,當前節點的選擇只與其兒子有關,滿足無後效性,可以選擇樹狀dp,於是建樹,dfs;

#include

#include

using

namespace

std;

int f[6001][2],father[6001];

bool v[6001];

int n;

int find_max(int a,int b)

void dfs(int k)//f[i][0]儲存不選用當前人的最大值,f[i][1]儲存選用的最大值

}int main()

}memset(v,true,sizeof(v));

dfs(root);//從根節點開始搜尋

printf("%d\n",find_max(f[root][0],f[root][1]));//輸出決策是否選用第乙個人(第乙個人的陣列已儲存選與不選的最大值)

return

0;}

動態規劃 dp

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

DP動態規劃

include include include include include include includeusing namespace std 動態規劃 利用子問題求解整個問題 關鍵 記錄子問題的解 列出狀態轉移方程 寫法 遞推 由邊界向上,最終得到目標問題的解 遞迴 由目標問題出發,向下遞迴...

動態規劃(DP)

有n個重量和價值分別為wi和vi的物品。從這些物品中挑選出總質量不超過w的物品,求所有挑選方案中質量和的最大值。如果我去模擬一下這個問題 每個物品都可以選擇或不選擇。假設我從第i個物品挑選總重量小於j的物品 int rec int i,int j rec i 1,j 表示不選擇第i個物品 rec i...