chapter 16 贪心算法

1.活动选择问题

16.1-1 运用动态规划解决活动安排问题

//
//  main.cpp
//  pearls
//
//  Created by YangKi on 16/03/20.
//  Copyright © 2016年 YangKi. All rights reserved.

#include <cstdio>
#include <iostream>

#define Num 11 //the num of activity

using namespace std;
int s[Num+2]={0, 1, 3, 0, 5, 3, 5, 6, 8, 8, 2, 12, 16};
int f[Num+2]={0, 4, 5, 6, 7, 9, 9, 10, 11, 12, 14, 16, 17};
int c[Num+2][Num+2];// sij 代表在ai结束之后,aj开始之前的活动集合,c[i][j]表示sij的最大相互兼容的活动子集的个数
int subset[Num+2][Num+2];

void activity_arrange()
{
    for (int i=0; i < Num+1; i++)
        c[i][i+1] = 0;
    
    for (int i=0; i < Num+2; i++)
    {
        for (int j=0; j < Num+2; j++)
        {
            subset[i][j]=-1;
        }
    }
    
    for (int j=2; j<=Num+1; j++)
    {
        for (int i=j-2; i>=0; i--)
        {
            //get c[i][j]
            int temp=0;
            for (int k=i+1; k<j; k++)
            {
                if (s[k]>=f[i] && f[k]<=s[j])
                {
                    if (c[i][k]+c[k][j]+1 > temp)
                    {
                        temp = c[i][k]+c[k][j]+1;
                        subset[i][j]=k;
                    }
                }
            }
            c[i][j]=temp;
        }
    }
}


void print_sub(int i, int j)
{
    if (subset[i][j] != -1)
    {
        printf("a_%d\n", subset[i][j]);
        print_sub(i, subset[i][j]);
        print_sub(subset[i][j], j);
    }
}

int main()
{
    activity_arrange();
    printf("num:%d\n", c[0][Num+1]);

    print_sub(0, Num+1);
    return 0;
}

2.贪心算法原理

16.2-1 0-1背包问题

基本的

//  main.cpp
// 
//  Created by YangKi on 16/03/21.
//  Copyright © 2016年 YangKi. All rights reserved.
//  0-1背包问题
#include <cstdio>
#include <iostream>
#define Num 3 //the num of goods
#define Volume 50 // the volume of bag
using namespace std;
int w[Num+1]={50, 10, 20, 30};
int v[Num+1]={0, 60, 100, 120};
int c[Num+1][Volume+1]; //c[i][j]表示到第i个商品为止,总重量为j的范围内,能够得到的最大的价值,c[Num][Volume]就是答案

void zero_one_pack()
{
    for (int i = 0; i <= Num; ++i)
    {
        for (int j = 0; j < w[i]; ++j)
            c[i][j]=0;
    }

    c[0][Volume]=0;

    for (int i = 1; i <= Num; ++i)
    {
        for (int j = w[i]; j <= Volume; ++j)//j>= w[i],否则根本连第i个都放不下,更不用提前i个的情况
        {
            if (w[i] <= Volume)
            {
                if (c[i-1][j] < c[i-1][j-w[i]]+v[i])
                {
                  c[i][j] = c[i-1][j-w[i]]+v[i];
                  printf("c[%d][%d]=c[%d][%d-%d]+v[%d]\n", i, j, i-1, j, w[i], i);
                }
                else
                {
                    c[i][j] = c[i-1][j];
                    printf("c[%d][%d]=c[%d][%d]\n", i, j, i-1, j);
                }
            }
            else//包放不下该物品
            {
                c[i][j]=c[i-1][j];//肯定不放了
            }
        }
    }
}

int main()
{
    zero_one_pack();
    printf("result:%d\n", c[Num][Volume]);

    return 0;
}

优化了空间的, 注意里面的遍历方向

//  main.cpp
// 
//  Created by YangKi on 16/03/21.
//  Copyright © 2016年 YangKi. All rights reserved.
//  0-1背包问题
#include <cstdio>
#include <iostream>
#define Num 3 //the num of goods
#define Volume 50 // the volume of bag
using namespace std;
int w[Num+1]={50, 10, 20, 30};
int v[Num+1]={0, 60, 100, 120};
int c[Volume+1]; 

void zero_one_pack()
{
    for (int i = 0; i <= Volume; ++i)
        c[i]=0;

    for (int i = 1; i <= Num; ++i)
    {
        for (int j = Volume; j >= w[i]; --j)//!!!!!!!!!!!!!!!!!!
        {
            if (c[j] < c[j-w[i]]+v[i])
                {
                    c[j] = c[j-w[i]]+v[i];
                    printf("c[%d]=c[%d-%d]+v[%d]\n", j, j, w[i], i);
                }
        }
    }
}

int main()
{
    zero_one_pack();
    printf("result:%d\n", c[Volume]);

    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 贪心算法 贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上...
    fredal阅读 13,058评论 3 52
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 176,123评论 25 709
  • 今天3月13日,在川大附小的听了武凤霞老师的《莫高窟》,引发了我许多的思考。在边听边记的过程中,我一直在思考何为名...
    流雨木阅读 2,962评论 0 0
  • CPU在一段较短的时间内,是对连续地址的一段很小的主存空间频繁地进行访问,而对此范围以外地址的访问甚少,这种现象称...
    lintong阅读 4,540评论 0 2
  • 海角 那蔚蓝色的 背包 画手腕上的 手表 喜欢看你的 微笑 总那么自信 骄傲 今天的天气 刚好 约好一起去 海角 ...
    我是个诗人很业余阅读 1,126评论 0 1

友情链接更多精彩内容