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