题意: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 }