当前位置:编程学习 > C/C++ >>

贪心算法(一):活动安排问题

对很多最优化问题来说,采用动态规划方法来解决就有点大材小用了。有时候我们可以采用贪心算法来取代。贪心算
法是通过所做的局部最佳选择来产生一个全局最优解。而且和动态规划不同的是,它是通过自顶向下的方式来解决每
一个子问题。而活动安排问题可以说是贪心算法的一个入门学习。
 
当我看到这个问题时,首先就想到了自己大一做ACM时在杭电acm里遇到的一个题目:今年暑假不AC。可以说这个题
目就是活动安排问题的翻版,只是一个讲的是怎么安排最多活动,一个讲的是最多能看到的电视节目。但本质是一样
的。下面我就以今年暑假不AC这道题目来说明吧。
 
当时看到这道题的时候想的是排序,然后暴力找。开始是按开始时间排序的,结果发现这样做没什么意义。因为有的
节目开始很早,但可能是最晚一个接受的,这样的话不能保证能得出最大值。于是便以结束时间来排序,毫无疑问,
排在最前面的那个肯定可以看,然后以这个为基础,从后依次遍历,找到第一个开始时间大于这个结束时间的节目,
并将这个节目在数组中的下标i做一个标记,并设k = i,然后从这个节目开始继续往后遍历,找出第一个节目j,使
a[j].start >= a[k].end。然后设k = j,继续往后遍历。依此循环下去,直到遍历完所有节目。实现代码如下:
[cpp] 
#include<stdio.h>  
  
struct Node  
{  
    int s;  
    int e;  
};  
  
int main()  
{  
    int n;  
    int i, j, k;  
    int count;  
    Node a[100], temp;  
  
    while (scanf("%d", &n), n)  
    {  
        for (i = 0; i < n; i++)  
        {  
            scanf("%d%d", &a[i].s, &a[i].e);  
        }  
        for (i = 0; i < n - 1; i++)  
        {  
            for (j = 0; j < n - i - 1; j++)  
            {  
                if (a[j].e > a[j + 1].e)  
                {  
                    temp = a[j];  
                    a[j] = a[j + 1];  
                    a[j + 1] = temp;  
                }  
            }  
        }  
  
        count = 1;  
        k = 0;  
        for (i = 1; i < n; i++)  
        {  
            if (a[i].s >= a[k].e)  
            {  
                k = i;  //标记选中的节目  
                count++;  
            }  
        }  
        printf("%d\n", count);  
    }  
    return 0;  
}  
 
今天看了书才知道这用到了贪心思想,下面这个代码是根据书上提供的递归形式写的,意思是一样的。
[cpp]  
#include<stdio.h>  
  
struct Node  
{  
    int s;  
    int e;  
};  
  
int count;  
  
void fun (Node a[], int i, int n)  
{  
    int m = i + 1;  
    while ((m <= n) && (a[i].e > a[m].s))  
        m++;  
  
    if (m <= n)  
    {  
        count++;  
        fun (a, m, n);  
    }  
}  
  
int main()  
{  
    int n;  
    int i, j;  
    Node a[100], temp;  
  
    while (scanf("%d", &n), n)  
    {  
        for (i = 0; i < n; i++)  
        {  
            scanf("%d%d", &a[i].s, &a[i].e);  
        }  
        for (i = 0; i < n - 1; i++)  
        {  
            for (j = 0; j < n - i - 1; j++)  
            {  
                if (a[j].e > a[j + 1].e)  
                {  www.zzzyk.com
                    temp = a[j];  
                    a[j] = a[j + 1];  
                    a[j + 1] = temp;  
                }  
            }  
        }  
  
        count = 1;  
        fun(a, 0, n-1);  
        printf("%d\n", count);  
    }  
    return 0;  
}  
 
 
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,