DAG上的動態規劃

2021-09-08 20:04:17 字數 3228 閱讀 4763

(如需要課件ppt,聯絡我)

•dag

的定義

•dag

意思是有向無環圖,所謂有向無環圖是指任意一條邊有方向,且不存在環路的圖。

•注:並非是一棵樹,邊數可以

經典例題

巢狀矩形•有n

個矩形,每個矩形可以用

ab來描述,表示長和寬。矩形

x(ab)

可以巢狀在矩形

y(cd)

中當且僅當

a或者b(相當於旋轉

x90度)。例如(

1,5)可以巢狀在(

6,2)內,但不能巢狀在(

3,4)中。你的任務是選出盡可能多的矩形排成一行,使得除最後乙個外,每乙個矩形都可以巢狀在下乙個矩形內。

•分析

可巢狀是乙個二元關係,二元關係可以用圖來進行建模。若是

x可以放進

y中,則對x,

y建邊,因為乙個矩形不會直接的或者間接的巢狀在自己的內部,所以此時構成的圖便是乙個

dag,所求答案就是在

dag上找一條最長路

•建圖

•列舉每乙個點,然後遍歷其他所有點,若是滿足包含關係,則簡歷xà

y的關係,此時關係就相當於

dag的一條邊。以每個點作為起點,找到以此點作為根所能走到的最長的那條最長路,最後得到的答案就是所求結果。注意,矩形的放置方法可以顛倒,故建圖的時候需要將兩條邊長分別進行判斷。

ll s[105][105]; //儲存矩形之間的關係,若是j可以巢狀i,則s[i][j] = 1

struct nodep[105]; //儲存兩邊

for(i = 0;i < n;i++)

}

進行簡單的

dfs計算,返回以每個數為根節點的最長路,再維護乙個最大值

例如輸入 4

//主函式

for(i = 0;i < n;i++)

maxx = max(maxx,dfs(i));

執行11次

•容易發現計算每乙個點的時候,都要將他的子孫都分別計算一次,這樣會大大加大演算法的時間複雜度

•更容易發現,每當第一次計算完這個點的所有子孫以後,後面的數可以直接用,而不用再去分別計算一下各種點的貢獻

•所以,可以在計算的過程中,第一次就保留當前點的貢獻,並採用陣列記錄下來,如果下次 再次用到這個點,便可以直接返回當前點的值,而不用繼續採用遞迴的方式計算

•新方法:

記憶化搜尋

ll dp[n];

ll dfs(ll u)

執行9次

引入一種新方法

--動態規劃

若是將矩形按照邊長的大小排序,遍歷

n個矩形,可以發現若是矩形

j可以巢狀在矩形

i內,矩形

i可以巢狀的值就是矩形

j能巢狀的值

+1,遍歷所有能被

i巢狀的矩形,最後得到乙個最大值,也可以解決最長路的問題。 設

dp[i]

表示第i

個矩形可以巢狀的最大值,則有 dp

[i] = max(dp[

i],dp[j]+1)

得到乙個遞推式,此遞推式被稱在動態規劃中被稱為狀態轉移方程,是動態規劃的精髓。

int cmp(node a,node b)

sort(p,p+n,cmp);

for(i = 0;i < n;i++)

ll maxx = 0;

for(i = 0;i < n;i++)

maxx = max(maxx,dp[i]);

總結練習

•硬幣問題

•此問題的記憶化搜尋方案不再講述,注意初始化記錄陣列的時候,為了防止陣列的初始值與答案的相互影響,需要將陣列初始化為特殊值。

•正難則反,考慮一共有

s面額的錢,最後使得錢為

0的方案。

•類似dag求最長路,此問題也可以轉化為

dag上的路徑問題。

•錢數只能不斷的減少,所以不會存在成環的情況。錢數總是指向更小的面值,所以存在方向問題。

•考慮動態規劃的做法,dp[

i]表示面值為

i時所使用的硬幣數量的最值,則有遍歷每一種硬幣,若是

i>

面值vj dp

[i] = max/min(dp[

i],dp[

i-vj

]+1)

首先將對應的陣列進行初始化,最後得到結果。

/*

look at the star

look at the shine for u

*/#include#define ll long long

#define pii pair#define sl(x) scanf("%lld",&x)

using namespace std;

const int n = 1e6+5;

const int mod = 1e9+7;

const int inf = 0x3f3f3f3f;

const double pi = acos(-1);

ll inv(ll b)

ll fpow(ll n,ll k)return r;}

ll dp_min[n],dp_max[n],v[n];

int main()}}

printf("%lld %lld\n",dp_min[s],dp_max[s]);

return 0;

}

•要求:

•總結dag上的動態規劃的過程

•實現硬幣問題的記憶化搜尋

•了解硬幣問題的路徑輸出

•部落格總結

•完成uva10285

DAG上的動態規劃

dag模型 有n個矩形,每個矩形用兩個整數a,b描述,表示長和寬,矩形 a,b 可以巢狀在矩形 c,d 中,當且僅當a小於c,b小於d或b小於c,a小於d。要解決的問題就是從眾多矩形中選出最多的矩形,使其可以按要求排成一列,若有多解,矩形編號的字典序要盡可能小。分析 按照書上的分析很簡單易懂,也容易...

DAG上的動態規劃

時間限制 3000 ms 記憶體限制 65535 kb 難度 4 描述 有n個矩形,每個矩形可以用a,b來描述,表示長和寬。矩形x a,b 可以巢狀在矩形y c,d 中當且僅當a 輸入 第一行是乙個正正數n 0輸出 每組測試資料都輸出乙個數,表示最多符合條件的矩形數目,每組輸出佔一行 樣例輸入 1 ...

DAG 上的動態規劃

暫存 dag 上的動態規劃 訓練指南 大白書 2015年11月04日 16 42 48 閱讀數 1979 有向無環圖 dag,directed acyclic graph 上的動態規劃是學習動態規劃的基礎。很多問題都可以轉化為dag上的最長路 最短路或路徑計數問題。一 矩形巢狀 題目描述 有n個矩形...