ZJU-1093

 

DP,先对输入进行处理,每一个立方体处理为3个面,如有尺寸雷同面,则合并。
保证每个面的x<y。

然后为了减小无效搜索的次数,对于面进行了排序,以y为第一关键字,x为第二关键字,都是用quicksort,发现快速排序用起来真的是挺方便,不过不要排序直接DP应该也是没有问题的。

(当然merge sort还能更快,就是代码太多了。值得一提的是尽管merge sort和heap sort的最坏情况的复杂度都是比较排序的极限O(nlgn)但是其中隐含的参数还是有些区别的,merge sort要更快一些。)

排完了序以后,能放在第i个面上的面必定在0~i-1中,maxdone[]这个数组存储已经计算出的每个面上能包括该面能垒的最高高度,所以符合DP的要求
1.最优子结构:如果第i个面已经是最高高度,则它上面的i-1这个面以上也是i-1这个面可以垒的最高高度。
2.重叠子问题:重叠的子问题的结果存储在maxdone[]用来加速计算。

//2008-01-11 15:35:06 Accepted 1093 C++ 00:00.00 436K #include<stdio.h> struct piles{ int a,b; int h; }; struct piles pl[91]; int np; int maxdone[91]; int partb(int p,int r) { int x = pl[r].b; int i = p-1,j; struct piles t; for(j=p;j<=r-1;j++) { if(pl[j].b<=x) { i++; t=pl[j];pl[j]=pl[i];pl[i]=t; } } t=pl[r];pl[r]=pl[i+1];pl[i+1]=t; return i+1; } int parta(int p,int r) { int x = pl[r].a; int i = p-1,j; piles t; for(j=p;j<=r-1;j++) { if(pl[j].a<=x) { i++; t=pl[j];pl[j]=pl[i];pl[i]=t; } } t=pl[r];pl[r]=pl[i+1];pl[i+1]=t; return i+1; } void quicksort(int p,int r,int mode) { if(p<r) { int q; if(mode==2) q=partb(p,r); else if(mode==1) q=parta(p,r); quicksort(p,q-1,mode); quicksort(q+1,r,mode); } } int dpsolve(int key) { if(maxdone[key]!=0) return maxdone[key]; else { int i; int maxre=0,t,re=0; re += pl[key].h; for(i=key-1;i>=0;i--) { if(pl[i].a<pl[key].a && pl[i].b<pl[key].b) { t = dpsolve(i); if(t>maxre) maxre = t; } } maxdone[key] = re+maxre; return maxdone[key]; } } int main() { freopen("1093.txt","r",stdin); int n,x,y,z,d[3],i,j,k,t,min,count=0; int maxre,tre; while((scanf("%d",&n)!=EOF) && n!=0) { np=0; count++; for(k=0;k<n;k++) { scanf("%d %d %d",&d[0],&d[1],&d[2]); for(i=0;i<2;i++) { min=i; for(j=i+1;j<3;j++) { if(d[j]<d[min]) min = j; } if(min!=i) { t=d[i];d[i]=d[min];d[min]=t; } } x=d[0];y=d[1];z=d[2]; if(x==y && y==z) { pl[np].a = x;pl[np].b = y;pl[np].h = z;np++; } else if(x==y) { pl[np].a = x;pl[np].b = y;pl[np].h = z;np++; pl[np].a = x;pl[np].b = z;pl[np].h = y;np++; } else if(y==z) { pl[np].a = x;pl[np].b = y;pl[np].h = z;np++; pl[np].a = y;pl[np].b = z;pl[np].h = x;np++; } else { pl[np].a = x;pl[np].b = y;pl[np].h = z;np++; pl[np].a = x;pl[np].b = z;pl[np].h = y;np++; pl[np].a = y;pl[np].b = z;pl[np].h = x;np++; } } quicksort(0,np-1,2); k=0; for(i=1;i<np;i++) { if(pl[i].b==pl[k].b) continue; else { quicksort(k,i-1,1); k=i; } } quicksort(k,i-1,1); for(i=0;i<91;i++) { maxdone[i]=0; } maxre=0; for(i=0;i<np;i++) { tre = dpsolve(i); if(tre>maxre) maxre = tre; } printf("Case %d: maximum height = %ld/n",count,maxre); } fclose(stdin); return 0; } 

 

你可能感兴趣的:(ZJU-1093)