zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",temp);
    34             }
    35             else{
    36                 ans+=temp*cat[i].bili;
    37                 //printf("%.3lf
    ",temp);
    38                 break;
    39             }
    40         }
    41         printf("%.3lf
    ",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
    ",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
    ",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
    ");
    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
    ");
    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
    ",ans*200);
    42     }
    43     return 0;
    44 }
    View Code

     

  • 相关阅读:
    2019春第三次课程设计实验报告
    2019春第二次课程设计实验报告
    2019春第一次课程设计实验报告
    第十二周总结
    第十一周总结
    第五周课程总结&试验报告(三)
    第四周课程总结&实验报告(二)
    第三周课程总结&实验报告一
    第二周学习总结
    19春总结
  • 原文地址:https://www.cnblogs.com/tangjj-nenu/p/3259015.html
Copyright © 2011-2022 走看看