zoukankan      html  css  js  c++  java
  • NYOJ 16 矩形嵌套(经典动态规划)

    传送门

    Description

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

    Input

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

    Output

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

    Sample Input

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

    Sample Output

    5

    思路

      一、对于输入的a,b将较大的值赋给矩形的长,较小的值赋给矩形的宽,然后对矩形的长从小到大排序,这样保证了前面的矩阵不可能嵌套在后面中,然后只要对宽进行判断就行了。这样问题就转化为最长上升子序列了。

      二、利用图模型解决,假设X可以嵌套在Y中,就从X到Y连一条边,这个有向图是无环的,也就是DAG图,这样,问题转化为求DAG上的最长路径

     

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn = 1005;
    struct Node{
    	int len,wid;
    }node[maxn];
    
    bool cmp(struct Node xx,struct Node yy)
    {
    	if (xx.len == yy.len)	return xx.wid < yy.wid;
    	else	return xx.len < yy.len;
    }
    
    int main()
    {
    	int T;
    	scanf("%d",&T);
    	while (T--)
    	{
    		int N,l,w,res = 0;
    		int dp[maxn] = {0};
    		scanf("%d",&N);
    		for (int i = 0;i < N;i++)
    		{
    			scanf("%d%d",&l,&w);
    			node[i].len = l > w?l:w;
    			node[i].wid = w < l?w:l;
    		}
    		sort(node,node+N,cmp);
    		for (int i = 0;i < N;i++)     //转化为求最长上升子序列 
    		{
    			dp[i] = 1;
    			for (int j = 0;j < i;j++)
    			{
    				if (node[i].wid > node[j].wid && node[i].len > node[j].len && dp[j] + 1 > dp[i])
    				{
    					dp[i] = dp[j] + 1;
    				}
    			}
    			res = max(res,dp[i]);
    		}
    		printf("%d
    ",res);	
    	}
    	return 0;
    }
    

      

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 1005;
    struct Node{
    	int len,wid;
    }node[maxn];
    int dp[maxn],edge[maxn][maxn];
    
    bool cmp(struct Node x,struct Node y)
    {
    	if (x.len == y.len)	return x.wid < y.wid;
    	else	return x.len < y.len;
    } 
    
    void addedge(int N)
    {
    	for (int i = 0;i < N;i++)
    	{
    		for (int j = i + 1;j < N;j++)
    		{
    			if (node[i].len < node[j].len && node[i].wid < node[j].wid)	edge[i][j] = 1;
    		}
    	}
    }
    
    int solve(int i,int N)
    {
    	int &ans = dp[i];          //为表项dp[i]声明了一个引用,这样,任何对ans的读写实际上都是在对dp[i]进行,实际上,当dp[i]换成dp[i][j][k]这样的长名字,该技巧优势更明显
    	if (ans > 0)	return ans;
    	ans = 1;
    	for (int j = 0;j < N;j++)	if (edge[i][j])	ans = max(ans,solve(j,N) + 1);
    	return ans;
    }
    
    int main()
    {
    	int T,N,x,y;
    	scanf("%d",&T);
    	while (T--)
    	{
    		int tmp,res = 0;
    		memset(dp,0,sizeof(dp));
    		memset(edge,0,sizeof(edge));
    		scanf("%d",&N);
    		for (int i = 0;i < N;i++)
    		{
    			scanf("%d%d",&x,&y);
    			node[i].len = x>y?x:y;
    			node[i].wid = x<y?x:y;
    		}
    		sort(node,node+N,cmp);
    		addedge(N);
    		for (int i = 0;i < N;i++)
    		{
    			tmp = solve(i,N);
    			res = tmp>res?tmp:res;
    		}
    		printf("%d
    ",res);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    python算法(1)抓交通肇事犯
    vue(24)网络请求模块axios使用
    vue(23)Vuex的5个核心概念
    vue(22)Vuex的安装与使用
    JMeter分布式压测配置(五)
    命令行执行Jmeter脚本(四)
    BeanShell(二)
    Jmeter之测试片段(八)
    服务器资源监控之Perfmon
    Jmeter之线程组(四)
  • 原文地址:https://www.cnblogs.com/ZhaoxiCheung/p/5876685.html
Copyright © 2011-2022 走看看