そこNN矩形、各矩形は、BA、Bとの長さと幅を表し、説明することができます。矩形のX(a、b)はX(b)はネストすることができる場合、矩形Y(C、D)、Y(c、d)の場合に限り、<C、B <DA <C、B <DまたはB <C、A <DB <C <D(9090度回転に対応)。例えば、(1,51,5)は、(6,26,2)内にネストされてもよいが、中(3,43,4)ネストすることはできません。あなたの仕事は、多くの長方形が最後を除いて、各矩形は、次の長方形内にネストすることができるように、並んとして選出することです。
入力フォーマット
最初の行のが正の正数N(0 <N <10) N(0 <N <10)は、 テスト・データ・セットの数を示します。
各陽性試験データの最初の行は、正の数NNである(N \ル1000)(n≤1000)矩形番号に含まれるテストデータのセットを表します。
NN行目以降、二つの数字、B(0 <A、B \ル100)、B(0 <、b≤100)の各行は、長方形の長さおよび幅で表されます。
出力形式
各テスト出力データ最も適格矩形の数、行ごとに各出力を表す数。
各行の最後に余分なスペースが、その答えは、出力の有効性には影響を与えません。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int M[1000][1000],d[1000],n,maxn;//d数组存放从i开始最长序列
struct edge{
int x,y;
bool operator < (const edge& rhs)const{
return this -> x < rhs.x;
}
};
edge e[1000];
int dp(int i){//记忆化搜索
int& ans = d[i];//方法二 实用引用修改数组 方法一 利用赋值语句返回值
if(ans){
return ans;
}
ans = 1;
for(int j = 0;j < n; ++j){
if(M[i][j]){
ans = max(ans,dp(j) + 1);
}
}
return ans;
}
//void print(int i){
// printf("%d %d %d\n",i,e[i].x,e[i].y);
// for(int j = 0;j < n; ++j){
// if(M[i][j] && d[i] == d[j] + 1){
// print(j);
// break;
// }
// }
//}
int main(){
int T,i,j,mi;
cin >> T;
while(T--){
maxn = 0;
memset(M,0,sizeof(M));
memset(d,0,sizeof(d));
scanf("%d",&n);
for(i = 0;i < n; ++i){
scanf("%d%d",&e[i].x,&e[i].y);
if(e[i].x > e[i].y){
int tmp = e[i].x;
e[i].x = e[i].y;
e[i].y = tmp;
}
}
sort(e,e + n);
for(i = 0;i < n - 1; ++i){
for(j = i + 1;j < n; ++j){
if(e[i].y < e[j].y && e[i].x < e[j].x)
M[i][j] = 1;
}
}
/*for(i = n - 2;i >= 0; --i){//递推法
for(j = i + 1;j < n; ++j){
if(e[i].y < e[j].y && e[i].x < e[j].x)
//M[i][j] = 1;
d[i] = max(d[i],d[j] + 1);
if(d[i] > maxn)
maxn = d[i];
}
}*/
for(i = 0;i < n; ++i){
int t = dp(i);
if(t > maxn){
maxn = t;
mi = i;
}
}
printf("%d\n",maxn);
//print(mi);
}
return 0;
}
隣接行列ストレージ図を用いて、バイナリ関係ネスト長方形です。
状態遷移方程式D [I] = MAX(D [i]は、D [J] + 1)。