長方形ネスト(最小ディクショナリシーケンス)—DAGダイナミックプランニングの問題
2997 ワード
初歩学習DAG(有向無環図dp)
質問:
説明
長さと幅を表すn個の矩形があり、各矩形はa,bで記述することができる.矩形X(a,b)は、矩形Y(c,d)にネストすることができ、aのみ
入力
1行目は正の数N(0試験データのグループ毎の1行目は正の数nであり、このグループの試験データに矩形の個数(n<=1000)の次のn行が含まれていることを示し、各行には2つの数a,b(0 )がある
しゅつりょく
テストデータのセットごとに1つの数を出力し、最大条件を満たす矩形の数を表し、各グループの出力は1行を占めます.
サンプル入力
サンプル出力
分析:
長方形間の「ネスト可能」関係は典型的な二元関係であり、二元関係は図でモデリングすることができる.矩形Xが矩形Yにネストされている場合、XからYまで1本のエッジがあります.この有向図は、矩形が自分の内部に直接または間接的にネストできないため、リングがない.言い換えればDAGですこのように、私たちの任務はDAG上の最長の経路を求めることです.
コード:
もう1つの解法(単調上昇シーケンスに類似)
質問:
説明
長さと幅を表すn個の矩形があり、各矩形はa,bで記述することができる.矩形X(a,b)は、矩形Y(c,d)にネストすることができ、aのみ
入力
1行目は正の数N(0試験データのグループ毎の1行目は正の数nであり、このグループの試験データに矩形の個数(n<=1000)の次のn行が含まれていることを示し、各行には2つの数a,b(0 )がある
しゅつりょく
テストデータのセットごとに1つの数を出力し、最大条件を満たす矩形の数を表し、各グループの出力は1行を占めます.
サンプル入力
1
10
1 2
2 4
5 8
6 10
7 9
3 1
5 8
12 10
9 7
2 2
サンプル出力
5
分析:
長方形間の「ネスト可能」関係は典型的な二元関係であり、二元関係は図でモデリングすることができる.矩形Xが矩形Yにネストされている場合、XからYまで1本のエッジがあります.この有向図は、矩形が自分の内部に直接または間接的にネストできないため、リングがない.言い換えればDAGですこのように、私たちの任務はDAG上の最長の経路を求めることです.
コード:
#include"stdio.h"
#include"stdlib.h"
#include"algorithm"
#include"string.h"
#include"math.h"
using namespace std;
const int maxn=1005;
int g[maxn][maxn];
int maxx[maxn];//maxn[i] i ,
// : d[i]=max(d[j]+1) j=1,2...n;j i d[i] i
int path_all[maxn]; //
int n;
struct node
{
// , 、
int length;
int width;
}rec[maxn];
void Build_g() //
{
memset(g,0,sizeof(g));
for(int i=0;i0) return ans; //
ans=1; //
for(int j=0;jans)
{
ans=dp(i);
pos_max=i;
}
}
printf(" :
");
for(int i=0;i
もう1つの解法(単調上昇シーケンスに類似)
#include
#include
#include
using namespace std;
struct ans{
int x;
int y;
};
struct ans a[1001];
int dp[1001];
bool cmp(struct ans a,struct ans b)
{
if(a.x <= b.x) return 1;
else if(a.x == b.x && a.y < b.y)
return 1;
else return 0;
}
bool max(struct ans m,struct ans n)
{
if(m.x < n.x && m.y < n.y) return 1;
else return 0;
}
int main()
{
int n,m,i,j,k;
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
for(i = 0; i < m; i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
if(a[i].x > a[i].y)
{
int tmp = a[i].x;
a[i].x = a[i].y;
a[i].y = tmp;
}
}
sort(a,a+m,cmp);
memset(dp,0,sizeof(dp));
for(i = 1; i < m; i++)
{
for(j = 0; j <= i; j++)
{
if(max(a[j],a[i])&&dp[i] < dp[j] + 1)
{
dp[i] = dp[j] + 1;
}
}
}
int max = dp[0];
for(i = 0; i < m; i++)
{
if(max < dp[i])
max = dp[i];
}
printf("%d
",max+1);
}
return 0;
}