Rectangles
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 707 Accepted Submission(s): 284Problem DescriptionA rectangle in the Cartesian plane is speci ed by a pair of coordinates (x1 , y1) and (x2 , y2) indicating its lower-left and upper-right corners, respectively (where x1 ≤ x2 and y1 ≤ y2). Given a pair of rectangles,A = ((x A 1 , y A 1 ), (x A 2 ,y A 2 )) and B = ((x B 1 , y B 1 ), (x B 2 , y B 2 )), we write A ≤ B (i.e., A "precedes" B), if x A 2 < x B 1 and y A 2 < y B 1 :In this problem, you are given a collection of rectangles located in the two-dimension Euclidean plane. Find the length L of the longest sequence of rectangles (A 1,A 2,…,A L) from this collection such that A 1 ≤ A 2 ≤ … ≤ A L.InputThe input fi le will contain multiple test cases. Each test case will begin with a line containing a single integer n (where 1 ≤ n ≤ 1000), indicating the number of input rectangles. The next n lines each contain four integers x i 1 ,y i 1 ,x i 2 ,y i 2 (where -1000000 ≤ x i 1 ≤ x i 2 ≤ 1000000, -1000000 ≤ y i 1 ≤ y i 2 ≤ 1000000, and 1 ≤ i ≤ n), indicating the lower left and upper right corners of a rectangle. The end-of-file is denoted by asingle line containing the integer 0.OutputFor each input test case, print a single integer indicating the length of the longest chain.Sample Input3 1 5 2 8 3 -1 5 4 10 10 20 20 2 2 1 4 5 6 5 8 10 0
Sample Output2 1
题意:给你N个矩形的左下角跟右上角坐标,然后找出这样一组序列使得其中的每一项与它的后一项满足一个条件,条件是前一项的右上角顶点的X,Y坐标都比后一项的左下角顶点的小,这样的序列可能有多个,求出最长那个的长度(最后一项没有后一项,你懂的,他就是最大的那个)
解析:用记忆化搜索来减少重复搜索的时间,做了很多记忆化搜索题目的人基本很快KO这个题
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define Max(a,b) a>b?a:b
using namespace std;
int n;
int dp[1111],map[1111][1111];
struct node
{
int x1,x2,y1,y2;
}s[1111];
int dfs(int x)
{
int i,j,k,l;
if(dp[x])return dp[x]; //先前有数据了就不用再搜了
for(i=0;i<n;i++)
if(map[x][i])
{
dp[x]=Max(dp[x],dfs(i)+1); //dp[x]要记录的是最大的那个值,值:由这个点往后最长的序列长度
}
dp[x]=Max(dp[x],1); //当然如果是最大的那个就要赋值1
return dp[x];
}
int main (void)
{
int i,j,k,l,x1,x2,y1,y2,sum;
while(scanf("%d",&n)!=EOF&&n)
{
for(i=0;i<n;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
s[i].x1=x1;
s[i].x2=x2;
s[i].y1=y1;
s[i].y2=y2;
}
memset(map,0,sizeof(map));
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++) //建立关联方便搜索
for(j=0;j<n;j++)
{
if(s[i].x2<s[j].x1&&s[i].y2<s[j].y1)
{
map[i][j]=1;
}
}
sum=0;
for(i=0;i<n;i++) //可能最长的那个序列的第一个矩形不是输入序列中的第一个
{
sum=Max(sum,dfs(i));
}
printf("%d\n",sum);
}
return 0;
}
总结:记录最优状态,以后搜索到这里的时候就可以直接调用这个状态