chapter 4:貪心

  貪心搞了5天的時間。。。。略坑。貪心呢,其實就是一種思想,在對問題求解時,老是做出在當前看來是最好的選擇。也就是說,不從總體上加以考慮,它所做出的僅僅是在某種意義上的局部最優解(是不是全局最優,須要證實)。其實貪心用的最多的東西就是快排,我感受作的每題都用到了快排,有的也用到告終構體。java

  1.HDOJ 1009 FatMouse' Tradenode

    這一題是說catfood與javabean之間能夠互換,而後找最多能夠換多少個javabean。這就與交換率有關了,優先知足交換率高的,確定獲得的javabean就多 了。用結構體記錄,而後快排便可。ios

 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數組

    這題的基本解法:初始化數組,若是須要移動,自增一,表明一個操做,最後便歷,找出操做數作多的那個,就是咱們須要的最長時間。ide

 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 今年暑假不ACspa

    這個題就是一個安排時間表的題,有不少電視節目,而後告訴你開始時間和結束時間,問你最多能安排多少個節目。咱們能夠先對電視節目結束的時間進行排序,而後,向前找不衝突最多的電視節目個數就行。3d

 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 Stickscode

    題目意思是讓你求操做的時間,開機須要1分鐘,而後若是後一個的長度或質量比前一個小的話須要調整,須要1分鐘,求安排的最少時間。咱們排序的時候就能夠依據那個要求排序,先按長度的由小到大排序,若是長度相等就按質量由小到大排序。blog

 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
相關文章
相關標籤/搜索