DAG模型 巢狀矩陣

2022-04-04 23:11:04 字數 1904 閱讀 6916

有向無環圖上的動態規劃是學習動態規劃的基礎,很多問題都可以轉化為dag上的最長路、最短路或路徑計數問題。

巢狀矩陣

有n個矩陣,每個矩陣可以用兩個整數a,b描述,表示它的長和寬。矩陣x(a,b)可以巢狀在矩陣y(c,d)中當且僅當a。)例如(1,5)可以巢狀在(6,2)內,但不能巢狀在(3,4)內。你的任務是選出盡量多的矩陣排成一行,使得除了最後乙個只之外,每乙個矩形都可以巢狀在下乙個矩形內。

分析:

矩陣之間的「可巢狀」關係是乙個典型的二元關係,二元關係可以用圖來建模。如果矩形x可以巢狀在矩形y裡,我們就從x到y連一條有向邊,這個圖是無環的,因為乙個矩形無法直接或者間接地巢狀在自己內部。換句話說,它是乙個dag,我們的任務便是求dag上的最長路徑。

設d(i)表示從結點i 出發的最長路長度。第一步只能到它的相鄰點,d(i) = max,其中e是邊集。最終答案是所有d(i)中的最大值。假設用鄰接矩陣儲存在矩陣g中。

記憶化搜尋**如下:

1 #include2 #include3 #include4 #include5

#define maxn 1000

6using

namespace

std;

7int

g[maxn][maxn], a[maxn], b[maxn], d[maxn], n, answer;

8int dp(inti)9

16void print_ans(int

i)1724}

2526

int path[maxn] = , cnt = 0;27

void print_all(int

i)28

36else

for(int j = 1; j <= n; ++j) if(g[i][j] && d[j]+1 ==d[i])

3740 --cnt;41}

42/*

43//作者的方法

44int path[maxn];

45void print_all(int cur, int i)

51for(int j = 1; j <= n; j++) if(g[i][j] && d[i] == d[j]+1)

52print_all(cur+1, j);53}

54*/

55int

main()

5675

}76 printf("

%d\n

", answer);

77print_ans(s);

78 printf("

\nall routes:\n");

79//

print_all(0, s);

80print_all(s);

81return0;

82 }

另一**如下:

1

//另附0ms 236kb的dp思路:按邊長降序排序,用類似lis的方法求解,只是比較元素大小的方法變成了比較長和寬

2 #include3 #include4 #include5 #include6

#define maxn 1008

7using

namespace

std;

8int

g[maxn][maxn], a[maxn], b[maxn], d[maxn], n;

9int dp(int

i)10

17int

main()

1839

}40 printf("

%d\n

", ans);41}

42return0;

43 }

矩陣巢狀(DAG)

題目 見紫書 思路都是根據紫書來的,然後重點是學習了一下利用結構體自定義矩陣的方法,這個方法確實比直接兩兩比較是否能夠巢狀優化了很多 大佬的 菜雞的 include include include using namespace std const int maxn 100 5 int depth ...

DAG模型 矩形巢狀

有n個矩形,每個矩形可以用兩個整數a,b描述,表示它的長和寬。矩形x a,b 可以巢狀在矩形y c,d 中,當且僅當 a 你的任務是選擇盡量多的矩形排成一行,使得除最後乙個矩形外所有矩形都可以巢狀在下乙個矩形內。如果存在多解,矩形編號的字典序應盡量小。如下 include include inclu...

巢狀矩形(DAG模型) 紫書訓練

題目描述 有n個矩形,每個矩形可以用a,b來描述,表示長和寬。矩形x a,b 可以巢狀在矩形y c,d 中當且僅當a紫書上有題目,但是沒有寫題出自 只好自己大致寫一下題目了.做題感受 經典的dp問題,但是由於我剛入門dp並不能特別快理解,想出來了還好說。思路 狀態轉移方程d i max.d i 表示...