0-1背包自顶向下非递归算法

三世轮回 提交于 2020-01-14 09:00:34
//0-1背包动态算法
//给出两点地杰斯特拉算法满足动态规划算法的需求
// A 到 b c d e f h 已知学生家的距离,求老师家到每个学生家的最短路径,好让王老师做出计划
// 写出0-1背包自顶向下的非递归动态规划算法

#include<iostream>
#include<string>
using namespace std;
int n;

int * input1()
{
    cout << "请输入物品总数n:" << endl;
    cin >> n;
    int *w = new int[n];
    cout << "请输入个物品的重量:" << endl;
    for (int i = 0; i < n; i++) {
        cin >> w[i];
    }

    return w;
}
int * input2() {
    int *v = new int[n];
    cout << "请输入各个物品的价值:" << endl;
    for (int i = 0; i < n; i++)
        cin >> v[i];
    return v;
}
int min(int a, int b) {
    if (a < b) return a;
    else return b;
}
int max(int a, int b) {
    if (a > b) return b;
    else return a;
}
//w[n] n件物品的重量;v[n] n个物品的权值 c是背包容量
void Knap(int *v, int *w, int c, int n, int **m)
{
    int jMax = min(w[n], c); //找出背包容量和最后一个物品重量的最小值
    for (int j = 0; j <jMax; j++)//初始化m[n][j]
        m[n][j] = 0;
    for (int j = w[n]; j <= c; j++)
        m[n][j] = v[n];            //初始化最后一行的非0
    for (int i = n - 1; i > 1; i--) {
        jMax = min(w[i], c);//当前物品重量与容量c的最小值
        for (int j = 0; j <= jMax; j++)
            m[i][j] = m[i + 1][j];
        for (int j = w[i]; j <= c; j++)
            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[2][c], m[2][c - w[1]] + v[1]);
}

void Traceback(int **m, int *w, int c, int n, int *x) {
    for (int 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 *w = input1();
    int *v = input2();
    int **m,c,*x;
    x = new int[n];
    m = new int *[n];
    for (int i = 0; i < n; i++)
        m[i] = new int[n];
    cout << "请输入背包容积:" << endl;
    cin >> c;
    Knap(v, w, c, n, m);
    Traceback(m, w, c, n, x);
    for (int i = 0; i <= n; i++)
        cout << x[i];

    system("pause");
    return 0;
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!