POJ 3018

题意:d维的n个箱子,装同样是d维的礼物,要求用一个套一个的方式装(每一维都要严格小于才能装进去),求最多用多少个箱子。如果不能装下的话就输出“Please look for another gift shop!

题解:由于箱子装下另一个箱子的条件是严格小于,所以装箱的图是一个有向无环图,然后在这上面找最长路即可(需要先对所有箱子的d维指数排序)。

View Code
 1 #include<cstdio>

 2 #include<cstring>

 3 #include<algorithm>

 4 using namespace std;

 5 int head[600],nc,tot[600];

 6 struct Edge

 7 {

 8     int to,next;

 9 }edge[500000];

10 void add(int a,int b)

11 {

12     edge[nc].to=b;edge[nc].next=head[a];head[a]=nc++;

13 }

14 void dfs(int now)

15 {

16     tot[now]=1;

17     int t=0;

18     for(int i=head[now];i!=-1;i=edge[i].next)

19     {

20         int to=edge[i].to;

21         if(!tot[to])

22             dfs(to);

23         t=max(tot[to],t);

24     }

25     tot[now]+=t;

26 }

27 int po[600][1005];

28 int n,d;

29 bool check(int a,int b)

30 {

31     for(int i=0;i<d;i++)

32         if(po[a][i]>=po[b][i])

33             return false;

34     return true;

35 }

36 int main()

37 {

38     while(scanf("%d%d",&n,&d)!=EOF)

39     {

40         for(int i=0;i<d;i++)

41             scanf("%d",&po[0][i]);

42         sort(po[0],po[0]+d);

43         memset(head,-1,sizeof(head));

44         nc=0;

45         memset(tot,0,sizeof(tot));

46         for(int i=1;i<=n;i++)

47         {

48             for(int j=0;j<d;j++)

49                 scanf("%d",&po[i][j]);

50             sort(po[i],po[i]+d);

51             for(int j=0;j<i;j++)

52             {

53                 if(check(i,j))

54                     add(i,j);

55                 else if(check(j,i))

56                     add(j,i);

57             }

58         }

59         if(head[0]==-1)

60         {

61             printf("Please look for another gift shop!\n");

62             continue;

63         }

64         dfs(0);

65         printf("%d\n",tot[0]-1);

66     }

67     return 0;

68 }

 

你可能感兴趣的:(poj)