恐怖水母=贪心算法+冒泡排序

恐怖水母

Time Limit: 3000ms, Memory Limit: 10000KB , Accepted: 3551, Total Submissions: 6402

Description

比基堡海滩有一个有n个触手的恐怖水母,蟹老板希望雇佣一些海绵宝宝把它杀死(即砍掉所有触手)。现在有m个海绵宝宝可以雇佣,一个能力值为x的海绵宝宝可以砍掉恐怖水母一只直径不超过x的触手,且需要支付x个金币。如何雇佣海绵宝宝才能杀死水母,并且支付的金币最少?需要注意一个海绵宝宝只能砍掉一只触手,并且不能被雇佣两次。

Input

第1行为正整数n和m,第2行为水母n只触手的直径,第3行为m个海绵宝宝的能力值,所有数据用空格间隔。

Output

输出最少金币数。如果无解,输出NULL

  • Sample Input 
    1. 2 3
    2. 5 4
    3. 7 8 4
  • Sample Output
    11

贪心算法:

贪心算法是什么意思?举个例子就很清楚了:现在你有一个能装4斤苹果的袋子,苹果有两种,一种3斤一个,一种2斤一个,怎么装才能得到最多苹果?当然我们人考虑的话当然是拿两个2斤的苹果,就刚好装满了,但是如果按贪心算法拿的话,首先就要把最重的苹果拿下(是不是很符合贪心两个字?),但并没有得到最多苹果。

贪心算法保证了局部最优,但并不能保证得到最优解。

什么时候用贪心法?满足下面两个条件

1.       具有最优子结构

2.       贪心选择性

扫描二维码关注公众号,回复: 2525749 查看本文章

第1点跟动态规划的条件一样,其实贪心跟动态规划一样,都是解决最优化的问题,而求解最优化问题通常又通过一系列的求解子问题的步骤。

第2点看个例子在说

现在有个活动选择的问题如下:
学校只有一个教室,下面表格i代表活动的编号,s代表活动开始时间,f代表活动结束时间.

i

1

2

3

4

5

6

7

8

9

10

11

s

1

3

0

5

3

5

6

8

8

2

12

f

4

5

6

7

9

9

10

11

12

14

16

 

现在问题是怎么合理分配才能让教室利用最大化(求活动序列A)?

如果用动态规划做的话思想可能是这样的,假设我已经知道第k个活动是活动序列之一,

那么又把1到k和k到11看做两个子问题继续分下去……(是不是感觉很麻烦- -)

用贪心法的话思想很简单:活动越早结束,剩余的时间是不是越多?那我就早最早结束的那个活动,找到后在剩下的活动中再找最早结束的不就得了?

虽然贪心算法的思想简单,但是贪心法不保证能得到问题的最优解,如果得不到最优解,那就不是我们想要的东西了,所以我们现在要证明的是在这个问题中,用贪心法能得到最优解。

现在要证明的是:

S是所有活动的集合,令m为活动集中最早结束的活动,则m在A活动序列中(A就是我们要求出的那个活动序列)。

证明:设j为A中最早结束的活动,如果m=j,那么就证明了最早结束活动m在A中,如果m!=j,

那么我们把j从A中剔除掉,然后换上m,依然能得到一个最优活动序列(m是所有活动中最早结束的),所以贪心法在这个问题里能得到最优解。

现在回过来看什么是贪心选择性质?就是能用贪心法得到得到全局最优解的性质,至于什么时候能获得,那就得自己判断了。

冒泡排序代码:
#include <stdio.h>
void BubbleSort(int s,int A[])
{
  int i,j,t;
  for(i=0;i<s-1;i++)
   for(j=0;j<s-1-i;j++)
    if(A[j]>A[j+1])
       t=A[j],A[j]=A[j+1],A[j+1]=t;
}
int main()
{
    int n,m,k,A[5],B[10];
    int i,j,s=0;
    scanf("%d %d",&n,&m);
    for(i=0;i<n;i++)scanf("%d",&A[i]);
    for(j=0;j<m;j++)scanf("%d",&B[j]);
    BubbleSort(n,A);
    BubbleSort(m,B);
    for (i=0;i<n;i++)
      for(j=i;j<m;j++)
        if(A[i]<=B[j]){
                       s=s+B[j];
                       break;
                      }
        if(A[0]>B[m-1]) printf("NULL\n");
        else printf("%d\n",s);
    return 0;

}

猜你喜欢

转载自blog.csdn.net/Chauncey_wu/article/details/80977971
今日推荐