2015 俄罗斯网络赛 Layer Cake
题意:给你n个蛋糕,有长和宽,高度均为1,所有的蛋糕可以切除多余部分作为目标蛋糕的一层,但是小的不可以要,切除的部分扔掉(太浪费了),每层蛋糕大小要求都一样,求最大体积
分析:当时犯傻了,按照宽排序,选取一个宽,然后选择比这个宽大的长的最小,过了14组数据,后来又遍历所有数据,n3的算法超了
第二天想明白了,输入的时候先把所有的长宽固定(因为有的数据长宽是倒着的),然后按照宽对所有数据排序
从小到大枚举枚举宽,然后把宽大于等于该枚举的长加入数组,排序,因为宽已经确定了,排序之后选择一个长就可以知道比这个长还长的有多少个,把每次查询的n2算法优化为n log n,
然后选取最大值并记录长宽就行了。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 6 struct point{ 7 int a,b; 8 }p[4005]; 9 10 bool cmp(point a,point b){ 11 if(a.b<b.b) 12 return true; 13 if(a.b==b.b&&a.a<b.a) 14 return true; 15 return false; 16 } 17 18 unsigned long long dp[4005]; 19 20 unsigned long long R; 21 int A,B; 22 23 int main(){ 24 int n; 25 while(cin>>n){ 26 for(int i=0;i<n;i++){ 27 cin>>p[i].a>>p[i].b; 28 if(p[i].b>p[i].a) 29 swap(p[i].a,p[i].b); 30 } 31 sort(p,p+n,cmp); 32 unsigned long long ans=0; 33 for(int i=0;i<n;i++){ 34 R=0; 35 int t=p[i].b; 36 for(int j=i;j<n;j++) 37 dp[R++]=p[j].a; 38 sort(dp,dp+R); 39 for(int j=0;j<R;j++) 40 if(((R-j)*dp[j]*p[i].b)>ans){ 41 ans=(R-j)*dp[j]*p[i].b; 42 A=dp[j];B=p[i].b; 43 } 44 } 45 cout<<ans<<endl; 46 cout<<A<<" "<<B<<endl; 47 } 48 return 0; 49 }