算法专题——贪心算法

贪心算法正确性证明:

1.证明贪心选择性质:经过贪心选择,可以获得最优解

2.最优子结构:证明子问题最优解与贪心选择组合,结果依然是最优解

•All we really need to do is argue that an optimal solution to the subproblem, combined with the greedy choice already made, yields an optimal solution to the original problem.
例:
•每次选择与当前已选Interval重叠,且X_R最大的Interval即可
 
贪心算法相关OJ题目:
1.POJ 1042 Gone Fishing
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<string>
 5 using namespace std;
 6 
 7 #define N 30
 8 int f[N],d[N],t[N];
 9 int temp[N],result[N],_time[N][N];
10 int n,h;
11 
12 int _max(int a,int b)
13 {
14     return a>b?a:b;
15 }
16 
17 int main()
18 {
19     while ((cin>>n)&&(n!=0))
20     {
21         memset(f,0,sizeof(f));
22         memset(d,0,sizeof(d));
23         memset(t,0,sizeof(t));
24         memset(_time,0,sizeof(_time));
25         memset(result,0,sizeof(result));
26         cin>>h;
27         for (int i=0;i<n;i++)
28             cin>>f[i];
29         for (int i=0;i<n;i++)
30             cin>>d[i];
31         for (int i=0;i<n-1;i++)
32             cin>>t[i];
33         for (int i=0;i<n;i++)
34         {
35             memset(temp,0,sizeof(temp));
36             for (int j=0;j<n;j++)
37                 temp[j]=f[j];
38             int T=h*60;
39             for (int j=0;j<i;j++)
40                 T-=t[j]*5;
41             while (T>0)
42             {
43                 int maxi=0;
44                 for (int j=0;j<=i;j++)
45                 {
46                     if (temp[maxi]<temp[j]) maxi=j;
47                 }
48                 result[i]+=temp[maxi];
49                 _time[i][maxi]+=5;
50                 temp[maxi]=_max(temp[maxi]-d[maxi],0);
51                 T-=5;
52             }
53         }
54         int num=0;
55         for (int i=0;i<n;i++)
56         {
57             if (result[num]<result[i]) num=i;
58         }
59         for (int i=0;i<n;i++)
60             if (i<n-1) cout<<_time[num][i]<<", ";
61             else cout<<_time[num][i]<<" "<<endl;
62         cout<<"Number of fish expected: "<<result[num]<<endl;
63         cout<<endl;
64     }
65     return 0;
66 }
View Code
2.NYOJ 248 BUYING FEED II
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<string>
 6 using namespace std;
 7 
 8 #define N 110
 9 int location[N],weight[N],price[N];
10 
11 int main()
12 {
13     int k,e,n;
14     while (scanf("%d",&k)!=EOF)
15     {
16     cin>>e>>n;
17     for (int i=0;i<n;i++)
18         cin>>location[i]>>weight[i]>>price[i];
19     for (int i=0;i<n;i++)
20         price[i]+=(e-location[i]);
21     int cost=0;
22     while (k>0)
23     {
24         int min;
25         for (int i=0;i<n;i++)
26             if (weight[i]!=0)
27             {
28                 min=i;break;
29             }
30         for (int i=0;i<n;i++)
31             if ((price[min]>price[i])&&(weight[i]!=0)) min=i;
32         if (k<=weight[min])
33         {
34             weight[min]-=k;
35             cost+=k*price[min];
36             k=0;
37         }
38         else 
39         {
40             k-=weight[min];
41             cost+=weight[min]*price[min];
42             weight[min]=0;
43         }
44     }
45     cout<<cost<<endl;
46     }
47     return 0;
48 }
View Code

此题需注意:若输入以EOF结束,则应用

 while (scanf("%d",&k)!=EOF)

进行处理

3.HDU 1052 The Horse Racing
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 
 6 int a[1001],b[1001];
 7 
 8 int main()
 9 {
10     int n;
11     while ((cin>>n)&&(n!=0))
12     {
13         memset(a,0,sizeof(a));
14         memset(b,0,sizeof(b));
15         for (int i=0;i<n;i++)
16             cin>>a[i];
17         for (int i=0;i<n;i++)
18             cin>>b[i];
19         sort(a,a+n);
20         sort(b,b+n);        //a,b均已排好序,下面依次从后往前遍历即可
21                             //显然不可能次次排序,在比完后如何去掉用过的元素?
22         int money = 0;
23         for (int i=n-1;i>=0;i--)
24         {
25             if (b[i]>a[i])
26             {
27                 money-=200;
28                 int temp=a[0];
29                 for (int j=0;j<i;j++)
30                     a[j]=a[j+1];
31                 a[i]=temp;
32             }
33             else if (b[i]<a[i])
34             {
35                 money+=200;
36                 int j=i;
37                 while ((b[i]<a[j])&&(j>=0)) j--;
38                 int temp=a[j+1];
39                 for (int k=j+1;k<i;k++)
40                     a[k]=a[k+1];
41                 a[i]=temp;
42             }
43             //若出现相等情况,则比较复杂
44             else if (b[i]==a[i])
45             {
46                 if (a[0]>b[0])
47                 {
48                     money+=200;
49                     int temp1=a[0],temp2=b[0];
50                     for (int j=0;j<i;j++)
51                     {
52                         a[j]=a[j+1];
53                         b[j]=b[j+1];
54                     }
55                     a[i]=temp1;    
56                     b[i]=temp2;
57                 }
58                 else
59                 {
60                     if (a[0]<a[i]) money-=200;
61                     int temp=a[0];
62                     for (int j=0;j<i;j++)
63                         a[j]=a[j+1];
64                     a[i]=temp;
65                 }
66             }
67         }
68         cout<<money<<endl;
69     }
70     return 0;
71 }
View Code
4.HDU 1051 Wooden Sticks
 1 /*基本思路:将木块按长度依次排序,长度相同按重量排序,然后从第一个没有用过的木块开始向后搜,找一个上升序列,重复以上过程直到所有元素均被用完,总共的上升序列个数即为最小准备时间
 2 */
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cstring>
 6 using namespace std;
 7 
 8 #define N 5001
 9 struct wood
10 {
11     int l;
12     int w;
13 }stick[N];
14 int flag[N];
15 
16 bool cmp(wood a,wood b)
17 {
18     if (a.l<b.l) return 1;
19     else if (a.l>b.l) return 0;
20     else return (a.w<b.w);
21 }
22 
23 int main()
24 {
25     int count;
26     cin>>count;
27     for (int k=0;k<count;k++)
28     {
29         memset(flag,0,sizeof(flag));
30         memset(stick,0,sizeof(stick));
31         int n,num=0,f=0;
32         cin>>n;
33         for (int i=0;i<n;i++)
34             cin>>stick[i].l>>stick[i].w;
35         sort(stick,stick+n,cmp);
36         while (f<n-1)
37         {
38             for (int i=0;i<n;i++)
39             {
40                 if (flag[i]==0)
41                 {
42                     f=i;
43                     flag[i]=1;
44                     num++;
45                     break;
46                 }
47                 f=n-1;
48             }
49             int temp=f;
50             for (int i=f+1;i<n;i++)
51             {
52                 if ((stick[i].w>=stick[temp].w)&&(flag[i]==0))
53                 {
54                     flag[i]=1;
55                     temp=i;
56                 }
57             }
58         }
59         cout<<num<<endl;
60     }
61     return 0;
62 }
View Code
5.POJ 1328 Radar Installation
6.POJ 1323 Game Prediction
 
 
原文地址:https://www.cnblogs.com/giddens/p/4336181.html