線性動規區間動規樹形動規
區間動規
根據題目要求,全域性最優滿足區域性最優;
典型題例
加分二叉樹(洛谷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...