有向無環圖上的動態規劃是學習動態規劃的基礎,很多問題都可以轉化為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 表示...