(dag模型+最长路+字典序)嵌套矩形
題目:
有 n 個矩形,每個矩形可以用兩個整數 a, b 描述,表示它的長和寬。矩形 X(a, b) 可以嵌套在矩形 Y(c, d) 中當且僅當 a<c, b<d,或者 b<c, a<d(相當于把矩形 X 旋轉了 90°)。例如 (1, 5) 可以嵌套在 (6, 2) 內,但不能嵌套在 (3, 4) 內。
你的任務是選出盡量多的矩形,使得除了最后一個之外,每一個矩形都可以嵌套在下一個矩形內。
Input
第一行一個正整數 n (n <= 1000)。
接下來 n 行每行兩個正整數 a, b 表示矩形 i 的長和寬。
Output
第一行一個整數 k 表示符合條件的最多矩形數。
第二行 k 個整數依次表示符合條件矩形的編號,要求字典序最小。
Sample Input
8
14 9
15 19
18 12
9 10
19 17
15 9
2 13
13 10
Sample Output
4
4 8 3 2
分析與解答:
DAG意思是有向無環圖,所謂有向無環圖是指任意一條邊有方向,且不存在環路的圖
矩形之間的“可嵌套”關系是一個典型的二元關系,二元關系可以用圖來建模。如果矩 形X可以嵌套在矩形Y里,就從X到Y連一條有向邊。這個有向圖是無環的,因為一個矩形無 法直接或間接地嵌套在自己內部。換句話說,它是一個DAG。這樣,所要求的便是DAG上 的最長路徑。
方法
仿照數字三角形的做 法,設d(i)表示從結點i出發的最長路長度,第一步只能走到它 的相鄰點,狀態轉移方程:d(i) = max { d(j) + 1 | (i,j) ∈E)
最終答案是所有d(i)中的最大值。
要先把圖建立出來,假設用鄰接矩陣保存在 矩陣G中。接下來編寫 記憶化搜索程序(調用前需初始化d數組的所有值為0):
思考總結
1.
他初始化為0,我初始化為-1,如果矩陣的邊相等,那么我是沒有對這個鄰接矩陣賦值的,因此,劉汝佳的代碼不能直接套用,必須加上==1
2.
大家看題:除了最后一個之外,每一個矩形都可以嵌套在下一個矩形內。
我們鄰接矩陣是根據 矩形X可以嵌套在矩形Y里,就從X到Y連一條有向邊來建立的
說明最后一個一定是大矩形
那么打印出來就是由小矩形到大矩形的,
d(i)表示從結點i出發的最長路長度
這個路是以那個最大矩形為終止點的
那我們寫dfs遞歸的意思是,d(i)嵌套在d(j)里,(d(i)比d(j)小),同時d(j)到最大矩形的距離最大
如果有多個最優解,矩形編號的字典序應最小。將所有d值計算出來以后,選擇最最大d[i]所對應的i。如 果有多個i,則選擇最小的i,這樣才能保證字典序最小。接下來可以選擇d(i)=d(j)+1且 (i,j)∈E的任何一個j。為了讓方案的字典序最小,應選擇其中最小的j
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std;const int maxN=2000;int n; int A[maxN]; int B[maxN]; int G[maxN][maxN]; int F[maxN];int dfs(int x); void print_ans(int ans);int main() {memset(F,-1,sizeof(F));memset(G,-1,sizeof(G));cin>>n;for (int i=1;i<=n;i++){cin>>A[i]>>B[i];}for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)if (((A[i]<A[j])&&(B[i]<B[j]))||((A[i]<B[j])&&(B[i]<A[j])))G[i][j]=1;for (int i=1;i<=n;i++)if (F[i]==-1)F[i]=dfs(i);int Ans=0;for (int i=1;i<=n;i++)if (F[i]>F[Ans])Ans=i;cout<<F[Ans]<<endl;print_ans(Ans);cout<<endl;return 0; }int dfs (int i){int & ans=F[i];if(ans>0) return ans;ans=1;for(int j=1;j<=n;++j){if(G[i][j]==1) ans=max(ans,dfs(j)+1);} return ans; }void print_ans(int i){printf("%d ",i);for(int j=1;j<=n;++j){//選最小的j if(G[i][j]==1&&(F[i]==F[j]+1)){print_ans(j);break;} } } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的(dag模型+最长路+字典序)嵌套矩形的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 函数对象应用
- 下一篇: java虚拟机堆栈工作原理_java虚拟