题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3255
题目大意:给你多块蔬菜地,蔬菜地有重叠部分,每部分种的蔬菜可能相同也可能不同,重叠部分种植蔬菜价值最贵的,最后让你求最大利润。
解题思路:
这是我做的最坑爹的一题,几乎让我快哭了,Wrong answer了三十多次, 重拍了五六次代码。
每块蔬菜地种植蔬菜收获的利润为 val=x*y*price。 面积乘以价格,题目的重点转换在于如何确定重叠区域怎么让它种植最贵的蔬菜。
观察利润计算公式 : x*y*price <==> x*y*h 可以转换为求体积并。
说实话,这题一看真的很简单,一交就是一直错,代码每个部分都有调试N遍。 昨天一个就一直在调试,五个小时无果。和别人一对照,思路一点都没错,今天下午再重拍了一遍代码,又开始了Wrong answer之路,然后带着那颗受伤的心去改数组范围。点最大3W, 我线段树开12W多,存X的点开6W多。 点开4W错, 6WTLE, 索性所有数组范围开150005,错。 150101 AC。 我想哭了.....
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 #define lson l,mid,ID<<1 8 #define rson mid+1,r,ID<<1|1 9 const int maxn=150101; 10 typedef long long lld; 11 int flag[maxn]; 12 lld sum[maxn]; 13 int X[maxn], Z[maxn]; 14 15 struct Node ///这题快把我整哭了 16 { 17 int lx, rx, y, z, s; 18 Node(){} 19 Node(int lx_, int rx_ , int y_, int z_, int s_) 20 { 21 lx=lx_, rx=rx_, y=y_, z=z_, s=s_; 22 } 23 bool operator<(const Node &S) const 24 { 25 if(y==S.y) return s>S.s; 26 else return y<S.y; 27 } 28 }line[maxn], tmp[maxn]; 29 30 31 int find(int x, int M) 32 { 33 int l,r,m; 34 l=1; 35 r=M; 36 while(l<=r) 37 { 38 m=(l+r)>>1; 39 if(X[m]==x) 40 return m; 41 if(X[m]<x) 42 l=m+1; 43 else 44 r=m-1; 45 } 46 } 47 void Push_up(int ID,int l,int r) 48 { 49 if(flag[ID])sum[ID]=X[r+1]-X[l]; 50 else if(l==r)sum[ID]=0; 51 else sum[ID]=sum[ID<<1]+sum[ID<<1|1]; 52 } 53 void Update(int x,int y,int z,int l,int r,int ID) 54 { 55 int mid; 56 if(x<=l&&r<=y) 57 { 58 flag[ID]+=z; 59 Push_up(ID,l,r); 60 return ; 61 } 62 mid=(l+r)>>1; 63 if(x<=mid) 64 Update(x,y,z,lson); 65 if(y>mid) 66 Update(x,y,z,rson); 67 Push_up(ID,l,r); 68 } 69 70 int main() 71 { 72 int n, m, T, tcase=0; 73 cin >> T; 74 while(T--) 75 { 76 cin >> n >> m; 77 Z[0]=0; 78 for(int i=1; i<=m; i++) 79 cin >> Z[i]; 80 int num=0; 81 for(int i=0; i<n; i++) 82 { 83 int x1, x2, y1, y2, id; 84 scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&id); 85 line[++num]=Node(x1,x2,y1,Z[id],1); 86 X[num]=x1; 87 line[++num]=Node(x1,x2,y2,Z[id],-1); 88 X[num]=x2; 89 } 90 sort(Z,Z+m+1); 91 sort(X+1,X+num+1); 92 sort(line+1,line+num+1); 93 int ep=1; 94 for(int i=2; i<=num; i++) 95 if(X[i]!=X[ep]) X[++ep]=X[i]; 96 lld ans=0; 97 for(int i=0; i<m; i++) 98 { 99 memset(sum,0,sizeof(sum)); 100 memset(flag,0,sizeof(flag)); 101 lld tp=0, cnt=0; 102 for(int j=1; j<=num; j++) 103 if(line[j].z>Z[i]) tmp[++cnt]=line[j]; 104 for(int j=1; j<cnt; j++) 105 { 106 int l=find(tmp[j].lx,ep); 107 int r=find(tmp[j].rx,ep)-1; 108 Update(l,r,tmp[j].s,1,ep-1,1); 109 tp+=sum[1]*(lld)(tmp[j+1].y-tmp[j].y); 110 } 111 ans+=tp*(lld)(Z[i+1]-Z[i]); 112 } 113 printf("Case %d: %I64d\n",++tcase,ans); 114 } 115 return 0; 116 }