NYOJ16 矩形嵌套 (DAG/DP)

                                          矩形嵌套

题目描述:

有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度)。例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中。你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内。

输入描述:

第一行是一个正正数N(0<N<10),表示测试数据组数,
每组测试数据的第一行是一个正正数n,表示该组测试数据中含有矩形的个数(n<=1000)
随后的n行,每行有两个数a,b(0<a,b<100),表示矩形的长和宽

输出描述:

每组测试数据都输出一个数,表示最多符合条件的矩形数目,每组输出占一行

样例输入:

复制

1
10
1 2
2 4
5 8
6 10
7 9
3 1
5 8
12 10
9 7
2 2

样例输出:

5

第一种是DAG & 记忆化搜索求最长路,求从任意矩形开始的嵌套数量得到最大数量。

第二种方法是纯DP,从0滚动到MAX_N - 1,得到最终滚动值,数据量小的时候特别好用。

Code:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <climits>
#include <list>
using namespace std;
typedef long long ll;
#define lowbit(x) x & -x;
#define INF 0x3f3f3f3f;
#define PI 3.1415927 
const static int MAX_N = 1005;
struct Rec{
	int a;
	int b;
}rec[MAX_N];
int dp[MAX_N];
bool g[MAX_N][MAX_N];
int n;
int DAG(int s) {	//其实就是记忆化,求任意矩阵的嵌套数量
	if (dp[s]) return dp[s];
	dp[s] = 1;	//矩阵最小嵌套数为1
	for (int i = 0; i < n; i++) {
		if (g[s][i]) {
			dp[s] = max(dp[s], DAG(i) + 1);
		}
	}
	return dp[s];
}
void buildGraph() {	//构建DAG图(有向无环图)
	memset(g, false, sizeof(g));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (rec[i].a > rec[j].a && rec[i].b > rec[j].b) {
				g[i][j] = true;		//相当于DAG中a可达b
			}
		}
	}
}
/*按字典序打印DAG路径*/
void printGraph(int s) {
	printf("%d ", s);
	for (int i = 0; i < n; i++) {
		if (g[s][i] && dp[s] == dp[i] + 1) {
			printGraph(i);
			break;
		}
	}
}
int main() {
	int T;
	scanf("%d", &T);
	while (T--) {
		scanf("%d", &n);
		for (int i = 0; i < n; i++) {
			scanf("%d%d", &rec[i].a, &rec[i].b);	//长 >= 宽
			if(rec[i].a < rec[i].b){
				swap(rec[i].a, rec[i].b);
			}
		}
		buildGraph();
		memset(dp, 0, sizeof(dp));
		int res = 0;
		for (int i = 0; i < n; i++) {
			res = max(res, DAG(i));
		}
		printf("%d\n", res);
		/*多解情况下按字典序优先打印最大嵌套数路径
		for (int i = 0; i < n; i++) {
			if (dp[i] == res) {
				printGraph(i);
				break;
			}
		}*/
	}
	return 0;
}

Code: 

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <climits>
#include <list>
using namespace std;
typedef long long ll;
#define lowbit(x) x & -x;
#define INF 0x3f3f3f3f;
#define PI 3.1415927 
const static int MAX_N = 105;
int dp[MAX_N][MAX_N];
bool g[MAX_N][MAX_N];
int main() {
	int T;
	scanf("%d", &T);
	while (T--) {
		memset(g, false, sizeof(g));
		memset(dp, 0, sizeof(g));
		int n;
		scanf("%d", &n);
		for (int i = 0; i < n; i++) {
			int a, b;
			scanf("%d%d", &a, &b);
			g[a][b] = true;
			g[b][a] = true;
		}
		for (int i = 1; i < MAX_N; i++) {
			for (int j = 1; j < MAX_N; j++) {
				dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
				//比该矩阵长/宽小的矩阵的最大嵌套数,让最大值值一直往 MAX_N方向滚动
				if (g[i - 1][j - 1]) {	//存在长、宽均比改矩阵小的矩阵
					dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
				}
			}
		}
		printf("%d\n", dp[MAX_N - 1][MAX_N - 1]);
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
x1y2 x2y3 x3y1-x1y3-x2y1-x3y2 是计算三角形面积的公式中的一部分。 在这个公式中,x1、x2、x3分别表示三角形的三个顶点的x坐标,y1、y2、y3分别表示三角形的三个顶点的y坐标。通过计算这个表达式的值,可以得到三角形的面积。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [TetraCluster:使用并行Java 2库的Java并行程序。 该程序在群集并行计算机上运行,​​以从给定的点集中找到...](https://download.csdn.net/download/weixin_42171208/18283141)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [线性代数有个题,求正交变换x=Qy,化二次型f(x1,x2,x3)=8x1x2+8x1x3+8x2x3为标准型求出特征值](https://blog.csdn.net/weixin_39956182/article/details/115882118)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [nyoj-67-三角形面积(S=(1/2)*(x1y2+x2y3+x3y1-x1y3-x2y1-x3y2))](https://blog.csdn.net/weixin_30492601/article/details/99541033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值