贪心小练
贪心:
1.poj 1922
题意:一人从A地到B地,起始点时他要跟随第一个出发的人,之后如果有其他人追上初始他跟随的人时,
他便跟随这些人,求其到达目的地的时间。
首先考虑到这个时间应该等于他每次跟随其他人的各个时间总和,但是仔细的从总体思考,只需要算出他跟随的人到达目的地
的时间,找出最小时间,即是正解,因为不管你中间跟随了谁,最终还是会跟随最快的人,和他一起到达目的地,花费时间最少。
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 6 using namespace std; 7 8 int main() 9 { 10 int n,v,t,ans; 11 double st; 12 while(scanf("%d",&n)!=EOF&&n) 13 { 14 ans=1<<30; 15 for(int i=0;i<n;i++) 16 { 17 scanf("%d%d",&v,&t); 18 if(t>=0) 19 { 20 st=(4500*36)/(double)(v*10)+t; 21 if(st-(int)st>0) 22 st=(int)st+1; 23 if(ans>st) 24 ans=st; 25 } 26 } 27 printf("%d\n",ans); 28 } 29 return 0; 30 }
2.poj 2313
题意:要求得B序列使得
V = (|A(1)–B(1)|+ ...+|A(N)–B(N)|)+(|B(1)–B(2)|+...+|B(N-1)–B(N)|)最小
简化一下式子 |Ai-Bi|+|Bi-Bi-1|+|Bi-Bi+1|最小,也就是在Ai,Bi-1,Bi+1三个点间找一点是的上式的值最小
当然Bi=mid(Ai,Bi-1,Bi+1)这三个值的中间值,(1<i<n)即可保证V最小。
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<cstring> 6 #include<cmath> 7 8 using namespace std; 9 10 int cmp(int a,int b) 11 { 12 return a>b; 13 } 14 int mid(int a,int b,int c) 15 { 16 int mid[4]; 17 mid[0]=a;mid[1]=b;mid[2]=c; 18 sort(mid,mid+3,cmp); 19 return mid[1]; 20 } 21 int main() 22 { 23 int n,a[105],b[105],sum; 24 while(scanf("%d",&n)!=EOF) 25 { 26 sum=0; 27 for(int i=0;i<n;i++) 28 { 29 scanf("%d",&a[i]); 30 b[i]=a[i]; 31 } 32 for(int i=1;i<n-1;i++) 33 b[i]=mid(b[i-1],b[i+1],a[i]); 34 for(int i=0;i<n;i++) 35 sum+=abs(a[i]-b[i]); 36 for(int i=1;i<n;i++) 37 sum+=abs(b[i]-b[i-1]); 38 printf("%d\n",sum); 39 } 40 return 0; 41 }
3.poj 1328
题意: 给出在x轴上方的n个点,要在x轴上找最少的点以此为圆心,r为半径去覆盖那n个点。(经典贪心题目)
要学会转化问题,根据这n个点计算出覆盖该点圆心的区间,然后问题就转化为给你n个区间求得独立区间(即互不相交)的个数。
要使得点最少,就应该设置在区间右端点,若当前点的横坐标小于下一区间的左端点横坐标则计数加1,若当前点的横坐标大于下一区间
右端点横坐标则更新当前点的横坐标。
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<cstdlib> 6 7 using namespace std; 8 const int MAX=1005; 9 10 struct point 11 { 12 double r,l; 13 }p[MAX]; 14 15 int cmp(const void *a,const void *b) 16 { 17 point aa=*(point *)a; 18 point bb=*(point *)b; 19 if(aa.l>=bb.l) 20 return 1; 21 return -1; 22 } 23 24 int main() 25 { 26 int n,sum,flag,k=1; 27 double ans,x,y,r; 28 while(scanf("%d%lf",&n,&r)!=EOF) 29 { 30 sum=1; 31 flag=1; 32 if(n==0&&r==0) 33 break; 34 for(int i=0;i<n;i++) 35 { 36 scanf("%lf%lf",&x,&y); 37 if(r>=y&&flag) 38 { 39 p[i].l=x-sqrt(double(r*r-y*y)); 40 p[i].r=x+sqrt(double(r*r-y*y)); 41 } 42 else 43 flag=0; 44 } 45 printf("Case %d: ",k++); 46 if(!flag) 47 printf("-1\n"); 48 else 49 { 50 qsort(p,n,sizeof(p[0]),cmp); 51 ans=p[0].r; 52 for(int i=1;i<n;i++) 53 { 54 if(ans<p[i].l) 55 { 56 sum++; 57 ans=p[i].r; 58 } 59 else 60 if(ans>p[i].r) 61 ans=p[i].r; 62 } 63 printf("%d\n",sum); 64 } 65 66 } 67 return 0; 68 }
4.poj 1042
待续...