码迷,mamicode.com
首页 > 其他好文 > 详细

编程之美之买书问题

时间:2015-06-13 00:01:17      阅读:423      评论:0      收藏:0      [点我收藏+]

标签:编程之美

拿到这个问题,我的第一反应是用贪心算法,优先满足不同种类多的,这样打的折扣比价多。但是,看了书中的分析发现,*

我们设定的贪心策略实际上是有问题的, ie 在买 5 + 3 本的时候会出错。


技术分享
看到这里,书上说可以利用改进的贪心算法,感觉如果换了相应的折扣数量,可能又会有不同的结果了。因而,没有深入的研究下去。
既然,贪心算法不可行,那就用动态规划呗。
这里的动态规划思路很简单不过写起来有些复杂。我们这里用到了5维数组, 光是init 就写了好多。 其实我在写的时候,就在想有什么简单一点的方法可以方便的帮我把这一大堆数据初始化, 不过想了好久没能想到
<-_->!!

ps: 因为我们在写这个动态规划方法的时候,还没有看书中相应的动态规划部分的介绍。所以,我们的方法与书中是有些出入的,书中用的是 买书时候的“最小表示方法”, 按照买书的数量 保证 Y1 >= Y2 >= Y3 >= Y4 >= Y5。 我们这里没有这样的假定, 直接按照 i 对应 第 i 卷 书的数量。第 1 次用到 5 维数组,各种不舒服斯基 。。。。。。

为了方便,我们一如既往的使用了全局数组, 免去了数组传递时候的各种闹心事。 好吧,我只是太懒了 !!《-_-》!!

源代码如下:

// ================【买书】=================
// @ author         :       zhyh2010
// @ date           :       20150612
// @ version        :       1.1
// @ description    :       动态规划 考虑实际 各个种类的书的本数
// ===============【end 买书】=================

#include <stdlib.h>
#include <stdio.h>

#define NUM 10
#define DIMEMSION 5
#define UNINITAL 0
float g_discount[NUM + 1][NUM + 1][NUM + 1][NUM + 1][NUM + 1] = { UNINITAL };

#define MYPOS(x) (x < 0 ? 0 : x - 1)

void init()
{
    g_discount[1][0][0][0][0] = 0;
    g_discount[0][1][0][0][0] = 0;
    g_discount[0][0][1][0][0] = 0;
    g_discount[0][0][0][1][0] = 0;
    g_discount[0][0][0][0][1] = 0;

    g_discount[1][1][0][0][0] = 0.1;
    g_discount[1][0][1][0][0] = 0.1;
    g_discount[1][0][0][1][0] = 0.1;
    g_discount[1][0][0][0][1] = 0.1;
    g_discount[0][1][1][0][0] = 0.1;
    g_discount[0][1][0][1][0] = 0.1;
    g_discount[0][1][0][0][1] = 0.1;
    g_discount[0][0][1][1][0] = 0.1;
    g_discount[0][0][1][0][1] = 0.1;
    g_discount[0][0][0][1][1] = 0.1;

    g_discount[1][1][1][0][0] = 0.3;
    g_discount[1][1][0][1][0] = 0.3;
    g_discount[1][1][0][0][1] = 0.3;
    g_discount[1][0][1][1][0] = 0.3;
    g_discount[1][0][1][0][1] = 0.3;
    g_discount[1][0][0][1][1] = 0.3;
    g_discount[0][1][1][1][0] = 0.3;
    g_discount[0][1][1][0][1] = 0.3;
    g_discount[0][1][0][1][1] = 0.3;
    g_discount[0][0][1][1][1] = 0.3;

    g_discount[1][1][1][1][0] = 0.8;
    g_discount[1][1][1][0][1] = 0.8;
    g_discount[1][1][0][1][1] = 0.8;
    g_discount[1][0][1][1][1] = 0.8;
    g_discount[0][1][1][1][1] = 0.8;

    g_discount[1][1][1][1][1] = 1.25;
}

// 取6个数中的最大值
float mymax_f(float a, float b, float c, float d, float e, float f)
{
    float tmp_max = a;
    tmp_max = tmp_max > b ? tmp_max : b;
    tmp_max = tmp_max > c ? tmp_max : c;
    tmp_max = tmp_max > d ? tmp_max : d;
    tmp_max = tmp_max > e ? tmp_max : e;
    tmp_max = tmp_max > f ? tmp_max : f;

    return tmp_max;
}

// 根据之前数据 推到 当前 最大折扣
float mymax(int i, int j, int k, int l, int m)
{
    float max5 = UNINITAL;
    float max4 = UNINITAL;
    float max3 = UNINITAL;
    float max2 = UNINITAL;
    float max1 = UNINITAL;
    float max0 = UNINITAL;

    int cond = (i == 0) + (j == 0) + (k == 0) + (l == 0) + (m == 0);
    switch (cond)
    {
    case 0:
        max5 = g_discount[i - 1][j - 1][k - 1][l - 1][m - 1] + g_discount[1][1][1][1][1];
    case 1:
        max4 = g_discount[MYPOS(i - 1)][MYPOS(j - 1)][MYPOS(k - 1)][MYPOS(l - 1)][MYPOS(m - 1)] + g_discount[0][1][1][1][1];
    case 2:
        max3 = g_discount[MYPOS(i - 1)][MYPOS(j - 1)][MYPOS(k - 1)][MYPOS(l - 1)][MYPOS(m - 1)] + g_discount[0][0][1][1][1];
    case 3:
        max2 = g_discount[MYPOS(i - 1)][MYPOS(j - 1)][MYPOS(k - 1)][MYPOS(l - 1)][MYPOS(m - 1)] + g_discount[0][0][0][1][1];
    case 4:
        max1 = g_discount[MYPOS(i - 1)][MYPOS(j - 1)][MYPOS(k - 1)][MYPOS(l - 1)][MYPOS(m - 1)] + g_discount[0][0][0][0][1];
    case 5:
        max0 = g_discount[MYPOS(i - 1)][MYPOS(j - 1)][MYPOS(k - 1)][MYPOS(l - 1)][MYPOS(m - 1)] + g_discount[0][0][0][0][0];
        break;
    default:
        break;
    }

    return mymax_f(max0, max1, max2, max3, max4, max5); 
}


float computeDiscount(int x1, int x2, int x3, int x4, int x5)
{
    if (UNINITAL != g_discount[x1][x2][x3][x4][x5])
        return g_discount[x1][x2][x3][x4][x5];

    for (int i = 0; i != x1 + 1; i++)
    {
        for (int j = 0; j != x2 + 1; j++)
        {
            for (int k = 0; k != x3 + 1; k++)
            {
                for (int l = 0; l != x4 + 1; l++)
                {
                    for (int m = 0; m != x5 + 1; m++)
                    {
                        g_discount[i][j][k][l][m] = mymax(i, j, k, l, m);
//                      printf("x1 = %d, x2 = %d, x3 = %d, x4 = %d, x5 = %d本书的最低折扣为:\t%.2f\n",
//                          i, j, k, l, m, g_discount[i][j][k][l][m]);
                    }
                }
            }
        }
    }

    return g_discount[x1][x2][x3][x4][x5];
}

void main()
{
    init();
    int x1 = 3;
    int x2 = 2;
    int x3 = 1;
    int x4 = 1;
    int x5 = 1;
    computeDiscount(3, 2, 1, 1, 1);
    printf("买 x1 = %d, x2 = %d, x3 = %d, x4 = %d, x5 = %d本书的最低折扣为:\t%.2f\t\t价格为:%.2f\n",
        x1, x2, x3, x4, x5, g_discount[x1][x2][x3][x4][x5], 
        (x1 + x2 + x3 + x4 + x5 -g_discount[x1][x2][x3][x4][x5]) * 8);
}

编程之美之买书问题

标签:编程之美

原文地址:http://blog.csdn.net/zhyh1435589631/article/details/46474859

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!