DAG上的动态规划

矩形嵌套

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 4
描述
有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a
输入
第一行是一个正正数N(0 每组测试数据的第一行是一个正正数n,表示该组测试数据中含有矩形的个数(n<=1000)
随后的n行,每行有两个数a,b(0
输出
每组测试数据都输出一个数,表示最多符合条件的矩形数目,每组输出占一行
样例输入
1
10
1 2
2 4
5 8
6 10
7 9
3 1
5 8
12 10
9 7
2 2
样例输出
5

题意描述: 有n个矩形,每个矩形可以用两个整数a、b描述,表示它的长和宽,

       矩形(a,b)可以嵌套在矩形(c,d)当且仅当a

       要求选出尽量多的矩形排成一排,使得除了最后一个外,

       每一个矩形都可以嵌套在下一个矩形内,如果有多解,矩形编号的字典序应尽量小

  解题思路:<1>矩形之间的可嵌套关系是一个"二元关系",二元关系可以用图来建模。

       如果矩形X可以嵌套在矩形Y里,就从X到Y连一条有向边(G[x][y]=1)。

       这个图是无环的,因为一个矩形无法直接或间接地嵌套在自己内部,

       换句话说,他是一个DAG。

       这样,原问题便转化为求DAG上的最长路径。

       <2>那么如何求DAG最长上的最长路径呢?

         可定义状态: dp[i]表示从结点i出发所能到达的最长路径的长度

         那么: dp[i] = max(dp[j]) + 1, 其中G[i][j]=1,即i可嵌套在j中

         最后数组d中的最大值便是结果

       <3>如何保证最小字典序?

         在所有的d都计算出来以后,选择最大的d[i]所对应的i。

         如果有多个i,选择最小的i。(i即第一个起点)

         接下来可以选择d[i] = d[j]+1且(i,j)为边集的任何一个j,

         但为了保证字典序最小,应该选择其中最小的j,


#include 
#include 
#include 
using namespace std;

const int MAXN=1005;
int T,N;
int len[MAXN],wid[MAXN];
int G[MAXN][MAXN];
int d[MAXN],best=-(1<<30);
void build()	//建图
{
	for(int i=0;i0)
		return ans;
	ans=1;
	for(int j=0;j>T;
	while(T--)
	{
		memset(G,0,sizeof(G));
		memset(d,-1,sizeof(d));
		best=-(1<<30);
		int n;
		cin>>n;
		N=n;
		int i=0;
		while(n--)
		{
			int a,b;
			cin>>a>>b;
			if(b>a)
				swap(a,b);
			len[i]=a;
			wid[i]=b;
			++i;
			
		}
		build();
		for(int i=0;i


你可能感兴趣的:(ACM-动态规划)