0-1背包 动态规划

来源:互联网 发布:网络兼职干什么好 编辑:程序博客网 时间:2024/06/05 06:56
#include<stdio.h>
#include<iostream>
using namespace std;
#include<math.h>

typedef struct{
    int index;//物品的编号
    int w;//物品的重量
    int v;//物品的价值
}Goods;


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

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

void Knapsack(Goods *goods,int c, int m[20][20],int n){
    int jMax = min(goods[n].w - 1,c);
    //下面两个循环处理数组m的最后一行
    for(int j = 0;j <= jMax;j++)
        m[n][j] = 0;
    for(j = goods[n].w;j <= c;j++)
        m[n][j] = goods[n].v;

    for(int i = n - 1;i > 1;i--){
        jMax = min(goods[i].w - 1,c);
        for(j = 0;j <=jMax;j++)
            m[i][j] = m[i+1][j];
        for(j = goods[i].w;j <= c;j++)
            m[i][j] = max(m[i+1][j] , m[i+1][j - goods[i].w] + goods[i].v);
    }

    m[1][c] = m[2][c];
    if(c >= goods[1].w)
        m[1][c] = max(m[1][c],m[2][c-goods[1].w]+goods[1].v);

}

void Traceback(Goods *goods,int c,int m[20][20],int *x,int n){
    int weight = 0;//背包中物品的总重量
    int value = 0;//背包中物品的总价值
    for(int i = 1;i < n;i++)
        if(m[i][c] == m[i+1][c])
            x[i] = 0;
        else{
            x[i] = 1;
            c -=goods[i].w;
            weight += goods[i].w;
            value += goods[i].v;
        }
        x[n] = (m[n][c])?1:0;
        if(x[n]){
            weight += goods[n].w;
            value += goods[n].v;
        }

        cout<<"在背包中的物品为:";
        for(i = 1;i <= n;i++)
            if(x[i])
                cout<<goods[i].index<<"  ";

        cout<<"背包中物品的总重量为:"<<weight<<",总价值为:"<<value<<endl;
}

void main(){
    int n;//物品数量
    int c;//背包容量

    cout<<"输入物品数量:";
    cin>>n;
    cout<<"输入背包容量:";
    cin>>c;
    Goods *goods = new Goods[n+1];
    int *x = new int[n+1];//标记物品是否放入背包
    int m[20][20] = {0};
    cout<<"依次输入物品的重量和价值:\n";
        for(int i = 1;i <= n;i++)
        {
            cin>>goods[i].w>>goods[i].v;
            goods[i].index = i;

        }
        Knapsack(goods,c,m,n);
        Traceback(goods,c,m,x,n);
}






/*
#include<stdio.h>
#include<iostream>
using namespace std;
#include<math.h>

typedef struct{
    int index;//物品的编号
    int w;//物品的重量
    int v;//物品的价值
}Goods;


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

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

void Knapsack(Goods *goods,int c, int m[20][20],int n){
    int jMax = min(goods[n-1].w - 1,c);
    //下面两个循环处理数组m的最后一行
    for(int j = 0;j <= jMax;j++)
        m[n-1][j] = 0;
    for(j = goods[n-1].w;j <= c;j++)
        m[n-1][j] = goods[n-1].v;

    for(int i = n - 1;i > 1;i--){
        jMax = min(goods[i-1].w - 1,c);
        for(j = 0;j <=jMax;j++)
            m[i][j] = m[i+1][j];
        for(j = goods[i-1].w;j <= c;j++)
            m[i][j] = max(m[i+1][j] , m[i+1][j - goods[i-1].w] + goods[i-1].v);
    }

    m[0][c] = m[1][c];
    if(c >= goods[0].w)
        m[0][c] = max(m[0][c],m[1][c-goods[0].w]+goods[0].v);

}

void Traceback(Goods *goods,int c,int m[20][20],int *x,int n){
    int weight = 0;//背包中物品的总重量
    int value = 0;//背包中物品的总价值
    for(int i = 0;i < n-1;i++)
        if(m[i][c] == m[i+1][c])
            x[i] = 0;
        else{
            x[i] = 1;
            c -=goods[i].w;
            weight += goods[i].w;
            value += goods[i].v;
        }
        x[n-1] = (m[n-1][c])?1:0;

        cout<<"在背包中的物品为:";
        for(i = 0;i < n;i++)
            if(x[i])
                cout<<goods[i].index<<"  ";

        cout<<"背包中物品的总重量为:"<<weight<<",总价值为:"<<value<<endl;
}

void main(){
    int n;//物品数量
    int c;//背包容量

    cout<<"输入物品数量:";
    cin>>n;
    cout<<"输入背包容量:";
    cin>>c;
    Goods *goods = new Goods[n];
    int *x = new int[n];//标记物品是否放入背包
    int m[20][20] = {0};
    cout<<"依次输入物品的重量和价值:\n";
        for(int i = 0;i < n;i++)
        {
            cin>>goods[i].w>>goods[i].v;
            goods[i].index = i+1;

        }
        Knapsack(goods,c,m,n);
        Traceback(goods,c,m,x,n);
}*/
原创粉丝点击