(华为OJ)C 语言—购物单(背包问题和动态规划)

题目要求:
(华为OJ)C 语言—购物单(背包问题和动态规划)_第1张图片
解题思路:
本题和背包问题类似,再利用动态规划算法,计算再n钱时能购买的最大价值的物品,n值一直涨到最大值,求 出最大价值(详见代码备注)

代码如下:

/************************************************************************
*      文件名:Buylist
*      文件功能描述:购物单
*      文件作者名:Mr_han QQ:785937095
*      说明:
*       1、每个主件可以有 0 个、 1 个或 2 个附件。附件不再有从属于自己的附件
*       2、每件物品规定了一个重要度,分为 5 等:用整数 1 ~ 5 表示,第 5 等最重要
*       3、在不超过 N 元(可以等于 N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大
**************************************************************************/
#include 
#include 
#include 
#include 

#define LONG long
#define CHAR char
#define MAX_N 3000
#define MAX_M 10

LONG Knapsack ( LONG v[], LONG w[], LONG pro[], LONG N, LONG m)
{
    LONG c[MAX_M][MAX_N], i, j;           /*c[i][j]前i件物品在有j钱的时候可以获得最大价值*/
    bool flag[MAX_M][MAX_N];              /*flag[i][j]用表示第i件物品在有j钱的时候是否购买*/

    memset ( *c, 0, sizeof(c) );

    memset ( flag, false, sizeof(flag) );

    for ( i = 1; i <= m; i++ )
    {
        for ( j = 0; j <= N; j++ )
        {
            if ( pro[i] == 0 )          /*主件*/
            {
                c[i][j] = c[i-1][j];    /*先将前i-1件物品的乘积放入*/
                if( (v[i] <= j) && (c[i][j] < (c[i-1][j-v[i]] + v[i] * w[i]) ) )  /*取两者中较大值*/
                {
                    c[i][j] = c[i-1][j-v[i]] + v[i] * w[i];
                    flag[i][j] = true;
                }
            }
            else                        /*附件*/
            {
                    c[i][j] = c[i-1][j];
                    if( (v[i] <= j) && (c[i][j] < (c[i-1][j-v[i]] + v[i]*w[i]) ) )
                    {
                        if(flag[pro[i]][j-v[i]])    /*判断主件有没有购买*/
                            c[i][j] = c[i-1][j-v[i]] + v[i] * w[i];
                    }
            }
        }
    }

    return c[m][N];
}


LONG main()
{
	LONG v[MAX_M], w[MAX_M], pro[MAX_M], N, m, i;    /*v[]用来存放物品的价格,w[]用来存放物品的重要度,pro[]存放主附件*/
    printf ( "请输入总钱数和物品个数(空格间隔)、每个物品的价格和重要度和主附件(每个物品占一行):\n" );
	scanf("%d%d", &N, &m);
	for ( i=1; i<=m; i++ )
    {
        scanf ( "%d %d %d", &v[i], &w[i], &pro[i] );
    }

    printf ( "物品的价格与重要度乘积的总和的最大值为:%d \n", Knapsack (v, w, pro, N, m) );

    return 0;
}

你可能感兴趣的:(c语言)