DAG model-rectangular mosaic (dynamic programming)

DAG model-rectangle mosaic
n rectangles in a row, find out the more rectangles, so that the rectangle on the left can be embedded in the rectangle on the right. The rectangle satisfies the mosaic that is the length and width a, b on the left and the length and width c, d on the right: a<c and b<d or b<c and a<d
.
Idea : the mosaic between two rectangles can be converted into two points One-way through structure between. Convert n rectangles into an acyclic one-way graph , and then use the idea of dynamic programming to set a state d(i), which is the longest path state from point i.
After that, the state transition equation can be set up: d(i)=max(1,dp(j)+1)
Of course, remember that memorized search can greatly reduce the time complexity, so the initial words of state d(i) are marked as 0, in As long as you judge when searching, if it is greater than 0, you can directly trace back the previously calculated answer, reducing the process of repeated calculation.
Then find the longest path among all states d(i), but the problem requires finding the smallest number lexicographically , so if there are multiple answers, find the smallest i.
The i found is the best and smallest starting point lexicographic order, and the points behind him can be found by setting a function.
Note that the following points should be satisfied: you can pass through (can be embedded), the optimal option
code is as follows:

#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 105
struct nec
{
    
    
 int c;
 int k;
};
struct nec rect[maxn];
int n,d[maxn]={
    
    0};
int maxx=0,maxi=0,graph[maxn][maxn]={
    
    0};
void build()
{
    
    
 int i;
 for(i=1;i<=n;i++)
 {
    
    
  cin>>rect[i].c>>rect[i].k;
 }
}
int judge(int i,int j)
{
    
    
 if((rect[i].c<rect[j].c&&rect[i].k<rect[j].k)||(rect[i].c<rect[j].k&&rect[i].k<rect[j].c))
 return 1;
 return 0;
}
int dp(int i)
{
    
    
 int j;
 int& ans=d[i];
 if(ans>0)
 return ans;
 ans=1;
 for(j=1;j<=n;j++)
 {
    
    
  if(graph[i][j]==1)
  {
    
    
   ans=max(ans,dp(j)+1);
  }
 }
 return ans;
}
void print_ans(int i)
{
    
    
 int j;
 cout<<i<<" ";
 for(j=1;j<=n;j++)
 {
    
    
  if(graph[i][j]==1&&d[i]==d[j]+1)
  {
    
    
   print_ans(j);
   break;//很重要 
  }
 }
}
int main()
{
    
    
 int i,j;
 cin>>n;
 build();
 for(i=1;i<=n;i++)
 {
    
    
  for(j=1;j<=n;j++)
  {
    
    
   if(i==j)
   continue;
   graph[i][j]=judge(i,j);
  }
 }
 for(i=1;i<=n;i++)
 {
    
    
  dp(i);
 }
 for(i=1;i<=n;i++)
 {
    
    
  if(d[i]>maxx)
  {
    
    
   maxx=d[i];
   maxi=i;
  }
 }
 cout<<"max="<<maxx<<endl;
 print_ans(maxi);
 cout<<endl;
 return 0;
} 

Guess you like

Origin blog.csdn.net/HT24k/article/details/106227790