NOJ 1414 Rectangular Parallelopiped

来源:互联网 发布:淘宝主图视频如何上传 编辑:程序博客网 时间:2024/06/08 20:12
  • 问题描述
  • 有n个长方体,每个长方体可以用a,b,c来描述,表示长和宽。长方体(a,b,c)(a<=b<=c)可以嵌套在长方体(x,y,z)(x<=y<=z)内当且仅当a<x,b<y,c<z。例如(1,5,6)可以嵌套在(2,7,8)内,但不能嵌套在(1,2,30)内。你的任务是选出尽可能多的长方体排成一行,使得除最后一个外,每个长方体都可以嵌套在下一个长方体内。
  • 输入
  • 每组测试数据的第一行是一个正整数n,表示该组测试数据中含有长方体的个数(n<=1000)。
    随后的n行,每行有三个数a,b,c(0<a,b,c<100),表示长方体的长和宽和高。
  • 输出
  • 每组测试数据都输出一个数,表示最多符合条件的长方体数目,每组输出占一行。
  • 样例输入
  • 41 1 11 2 12 2 23 5 4
  • 样例输出
  • 3

类型:DAG上的最长路,排序DP
思路:
   1、把每一个长方体抽象成一个个的节点
   2、如果一个长方体可以覆盖另一个长方体,那么就在这两个长方体代表的节点上连一条有向边
   3、寻找到从某个节点出发可以得到的最长路
接下来就有一个问题:
  那么如何记录下从某个节点出发可以得到的最长路呢?
设dp[i]表示从节点i出发可以得到的最长路,第一步只能走到它的相邻点,则有
     dp[i] = max(dp[j]+1)  (i,j)属于边集



代码如下:

   

#include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> using namespace std; const int maxn=1000+5; struct REC { int l,r,h; }a[maxn]; int dp[maxn];//dp[i]表示从i开始能覆盖最多的长方体; inline int cmp(REC A,REC B) { return A.l<B.l; } int main() { int N,n,i,j,p,q,r; while(~scanf("%d",&n)) { int aa[3]; for(i=0;i<n;i++) { scanf("%d%d%d",&aa[0],&aa[1],&aa[2]); sort(aa,aa+3); a[i].l=aa[0]; a[i].r=aa[1]; a[i].h=aa[2]; dp[i]=1; } sort(a,a+n,cmp); int maxm=1; for(i=1;i<n;i++) { for(j=i-1;j>=0;j--) { if(a[i].l>a[j].l&&a[i].r>a[j].r && a[i].h >a[j].h&&dp[i]<dp[j]+1) dp[i]=dp[j]+1; } maxm=max(maxm,dp[i]); } printf("%d\n",maxm); } return 0; }





0 0
原创粉丝点击