0-1背包问题

#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#define MAX 100  

int w[MAX]; //存放物品重量
int v[MAX]; //存放物品价值
int x[MAX]; //x[i]=0表示第i个物品不装进背包,x[i]=1表示第i个物品装进背包
int m[MAX][MAX]; //m[i][j]表示可选物品为i+1,i+2..n,背包容量为j时,所装物品的最大价值

int min(int a, int b)
{
    return a<b?a:b;
}

int max(int a, int b)
{
    return a>b?a:b;
}

//返回背包所装物品最大价值
//n为总物品个数
//c为背包容量
int knapsack(int n, int c)
{
    int i, j;
    int jmax = min(c, w[n]); 
    for(j=1; j<jmax; j++) //初始边界值,只有一个物品可选{n},背包容量为j
        m[n][j] = 0;  //当物品重量大于背包容量时,不装入,没有产生效益
    for(j=jmax; j<=c; j++)
        m[n][j] = v[n];  //当物品重量大于背包容量时,不装入,产生效益

    for(i=n-1; i>1; i--)
    {
        int jmax = min(c, w[i]); 
        for(j=1; j<jmax; j++)  //当物品i不可装入背包中
            m[i][j] = m[i+1][j];
        for(j=jmax; j<=c; j++)  //当物品i可装入背包中时
            m[i][j] = max(m[i+1][j], m[i+1][j-w[i]]+v[i]);
    }
    m[1][c] = m[2][c];
    if(c>=w[1])
        m[1][c] = max(m[1][c], m[2][c-w[1]]+v[1]);
    return m[1][c];
}

//构造最优解
void TraceBack(int n, int c)
{
    int i;
    for(i=1; i<n; i++)
    {
        if(m[i][c] == m[i+1][c])
            x[i] = 0;
        else
        {
            x[i] = 1;
            c -= w[i];
        }
    }
    x[n] = m[n][c]?1:0;
}

int main()
{
    int n, c;
    printf("输入背包容量:");
    scanf("%d", &c);
    printf("输入物品个数:");
    scanf("%d", &n);
    printf("依次输入物品重量:");
    int i;
    for(i=1; i<=n; i++)
        scanf("%d", &w[i]);
    printf("依次输入物品价值:");
    for(i=1; i<=n; i++)
        scanf("%d", &v[i]);
    int u = knapsack(n, c);
    printf("背包所装物品最大价值为:%d\n", u);
    TraceBack(n, c);
    printf("装入的物品为:");
    for(i=1; i<=n; i++)
        if(x[i]==1)
            printf("%d ", i);
    printf("\n");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值