More AC !!!

要么不做,要么做到最好!

导航

chapter 4:贪心

  贪心搞了5天的时间。。。。略坑。贪心呢,其实就是一种思想,在对问题求解时,总是作出在当前看来是最好的选择。也就是说,不从整体上加以考虑,它所作出的仅仅是在某种意义上的局部最优解(是否是全局最优,需要证明)。其实贪心用的最多的东西就是快排,我感觉做的每题都用到了快排,有的也用到了结构体。

  1.HDOJ 1009 FatMouse' Trade

    这一题是说catfood与javabean之间可以互换,然后找最多可以换多少个javabean。这就与交换率有关了,优先满足交换率高的,肯定得到的javabean就多 了。用结构体记录,然后快排即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 struct node{
 8     int k;
 9     int i;
10     double bili;
11 }cat[1001];
12 int cmp(node a,node b){
13     return  a.bili>b.bili;
14 }
15 int main(){
16     int n,m;
17     while(scanf("%d%d",&m,&n)&&(m!=(-1))){
18         int f,j;
19         for(int i=0;i<n;i++){
20             scanf("%d%d",&j,&f);
21             cat[i].bili=(double)j/(double)f;
22             cat[i].i=f;
23             cat[i].k=j;
24         }
25         sort(cat,cat+n,cmp);
26         double temp=(double)m;
27         double ans=0;
28         for(int i=0;i<n;i++){
29            //printf("%d  %.2lf\n",cat[i].i,cat[i].bili);
30             if(temp>=(double)cat[i].i){
31                 temp-=(double)cat[i].i;
32                 ans+=(double)cat[i].k;
33                 //printf("%.3lf\n",temp);
34             }
35             else{
36                 ans+=temp*cat[i].bili;
37                 //printf("%.3lf\n",temp);
38                 break;
39             }
40         }
41         printf("%.3lf\n",ans);
42     }
43     return 0;
44 }
View Code

  2.HDOJ 1050 Moving Tables

    这题的基本解法:初始化数组,如果需要移动,自增一,代表一个操作,最后便历,找出操作数做多的那个,就是我们需要的最长时间。

 1 #include <iostream>
 2 #include <cmath>
 3 using namespace std;
 4 int p[205];
 5 int main()
 6 {
 7     int T , n , s ,d , t,min  , temp;
 8     cin >> T;
 9     while(T--)
10     {
11 
12             for(int j = 0; j < 200 ; j++)
13             {
14                 p[j] = 0;
15             }
16             cin >> t;
17             for(int j= 0 ; j < t ; j++)
18             {
19                 cin >> s >> d;
20                 s = (s - 1) / 2;//奇偶对门
21                 d = (d - 1) / 2;
22                 if(s > d)
23                 {
24                     temp = s;
25                     s = d ;
26                     d = temp;
27                 }
28                 for(int k = s ; k <= d; k++)
29                 {
30                     p[k] ++;
31                 }
32 
33             }
34             int max = -1;
35             for(int j = 0 ; j < 200 ; j++)//找出用得最多的那个
36             {
37                 if(p[j] > max)max = p[j];
38             }
39             cout << max *  10 <<endl;
40 
41     }
42     return 0;
43 }
View Code

  3.HDOJ 2037 今年暑假不AC

    这个题就是一个安排时间表的题,有很多电视节目,然后告诉你开始时间和结束时间,问你最多能安排多少个节目。我们可以先对电视节目结束的时间进行排序,然后,向前找不冲突最多的电视节目个数就行。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 struct jiemu{
 8     int start;
 9     int end;
10     int length;
11 }ti[101];
12 int cmp(jiemu a,jiemu b){
13     return a.end<b.end;
14 }
15 int main(){
16     int n;
17     while(scanf("%d",&n)&&n!=0){
18         int ti_s,ti_e;
19         for(int i=0;i<n;i++){
20             scanf("%d%d",&ti_s,&ti_e);
21             ti[i].start=ti_s;
22             ti[i].end=ti_e;
23             ti[i].length=ti_e-ti_s;
24         }
25         sort(ti,ti+n,cmp);
26         int ans=0,temp=ti[0].start;
27         for(int i=0;i<n;i++){
28             if(ti[i].start>=temp){
29                 ans++;
30                 temp=ti[i].end;
31             }
32         }
33         printf("%d\n",ans);
34     }
35     return 0;
36 }
View Code

  4.HDOJ 1051  Wooden Sticks

    题目意思是让你求操作的时间,开机需要1分钟,然后如果后一个的长度或质量比前一个小的话需要调整,需要1分钟,求安排的最少时间。我们排序的时候就可以依据那个要求排序,先按长度的由小到大排序,如果长度相等就按质量由小到大排序。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 
 8 struct sticks{
 9     int length;
10     int weigth;
11     int flag;
12 }arr[5001];
13 
14 int cmp(sticks a,sticks b){
15     if(a.length!=b.length)  return a.length<b.length;
16     else    return a.weigth<b.weigth;
17 
18 }
19 int main(){
20     int t;
21     scanf("%d",&t);
22     while(t--){
23         int n;
24         scanf("%d",&n);
25         for(int i=0;i<n;i++){
26             scanf("%d%d",&arr[i].length,&arr[i].weigth);
27             arr[i].flag=0;
28         }
29         sort(arr,arr+n,cmp);
30         int temp,ans=0;
31         for(int i=0;i<n;i++){
32             if(arr[i].flag==0){
33                 arr[i].flag=1;
34                 temp=arr[i].weigth;
35                 for(int j=i+1;j<n;j++){
36                     if(arr[j].flag==0&&arr[j].weigth>=temp){
37                         temp=arr[j].weigth;
38                         arr[j].flag=1;
39                     }
40                 }
41                 ans++;
42             }
43         }
44         printf("%d\n",ans);
45     }
46     return 0;
47 }
View Code

  5.HDOJ 2545 Degree Sequence of Graph G

    一句话,顶点的度序列 Havel 定理~

    定义:给出一个无向图的顶点度序列 {dn},要求判断能否构造出一个简单无向图。

    分析:

        贪心的方法是每次把顶点按度大小从大到小排序,取出度最大的点Vi,依次和度较大的那些顶点Vj连接,同时减去Vj的度。连接完之后就不再考虑Vi了,剩下的点再次排序然后找度最大的去连接……这样就可以构造出一个可行解。

判断无解有两个地方,若某次选出的Vi的度比剩下的顶点还多,则无解;若某次Vj的度减成了负数,则无解。
       

      至于什么是Havel定理,上面这个构造过程就是了~(转自别人的博客。。。。)。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 using namespace std;
 6 int d[1002];
 7 bool gr(int a,int b)
 8 {
 9     return a>b;
10 }
11 int main()
12 {
13     int t,n;
14     scanf("%d",&t);
15     while(t--){
16         scanf("%d",&n);
17         memset(d,0,sizeof(d));
18         for(int i=0;i<n;i++)
19             scanf("%d",&d[i]);
20         sort(d,d+n,gr);
21         int g=0;
22         while(d[0]!=0){
23             for(int k=1;k<=d[0];k++){
24                 d[k]--;
25                 if(d[k]<0){
26                     printf("no\n");
27                     g=1;
28                     break;
29                 }
30             }
31             d[0]=0;
32             sort(d,d+n,gr);
33             if(g==1)
34                 break;
35         }
36         if(g==0)
37             printf("yes\n");
38 
39     }
40     return 0;
41 }
View Code

  6.HDOJ 1052 Tian Ji -- The Horse Racing

    田忌赛马,求他的最优解。其实我觉得这题像模拟,因为题目已经把怎么选马告诉你了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 int arr1[1001],arr2[1001];
 8 int cmp ( const void *a , const void *b )
 9 {
10     return *(int *)a - *(int *)b;
11 }
12 int main(){
13     int n;
14     while(scanf("%d",&n)&&n!=0){
15         for(int i=0;i<n;i++)
16             scanf("%d",&arr1[i]);
17         for(int i=0;i<n;i++)
18             scanf("%d",&arr2[i]);
19         qsort(arr1,n,sizeof(int),cmp);
20         qsort(arr2,n,sizeof(int),cmp);
21         int begin1=0,begin2=0,ans=0,end1=n-1,end2=n-1;
22         while(begin1<=end1){
23             if(arr1[begin1]>arr2[begin2]){
24                 begin1++;
25                 begin2++;
26                 ans++;
27                 continue;
28             }
29             if(arr1[end1]>arr2[end2]){
30                 end1--;
31                 end2--;
32                 ans++;
33                 continue;
34             }
35             if(arr1[begin1]<arr2[end2]){
36                 ans--;
37             }
38             begin1++;
39             end2--;
40         }
41         printf("%d\n",ans*200);
42     }
43     return 0;
44 }
View Code

 

 

posted on 2013-08-15 10:05  Junkie_AC  阅读(171)  评论(0编辑  收藏  举报