多重背包遇到的问题,找了好久没找到原因

多重背包问题
我用的是把一个物品当成多个物品从而变为01背包问题,测试了几个答案没问题,但是测试到数据

30 100
12 15 1
15 18 1
6 9 4
32 43 1
24 12 92
5 5 3
13 26 4
2 3 3
14 9 7
31 28 77
19 18 88
18 17 70
21 23 4
19 24 3
29 37 2
33 34 4
25 32 5
28 47 4
1 1 2
23 25 3
24 30 1
22 24 1
4 7 1
33 40 2
15 29 4
18 9 51
19 17 25
6 10 4
24 20 15
18 23 5

出问题了,找了好久没找到原因。
求解答,

//多重背包问题
#include 
#include 
#include 
#define N 1010

typedef struct a {
    int data[100];
    int top;
} stack;

void init(stack *p) {
    p->top = -1;
}

void print(int *p, int n) {
    int i;
    for (i = 0; i <= n; i++) {
        printf("%d\t", p[i]);
    }
    printf("\n");
}

int pop(stack *p) {
    int end;
    if (p->top == -1)
        printf("NULL error\n");
    end = p->data[p->top--];
    return end;
}

void push(stack *p, int data) {
    if (p->top > 99)
        return;
    p->data[++p->top] = data;
}

int bin(int a) {
    stack list;
    int end, temp;
    init(&list);
    end = 0;
    while (a) {
        push(&list, a % 2);
        a = a / 2;
    }
    while (list.top >= 0) {
        temp = pop(&list);
        end = end * 10 + temp;
    }
    return end;
}

int count(int a) {
    int i;
    i = 0;
    while (a) {
        i++;
        a = a / 10;
    }
    return i;
}

int distract(int *value, int *weight, int *use, int *newvalue, int *newweight, int *n) {
    int i, num, counts, j, temp, m = 0;
    for (i = 1; i <= *n; i++) {
        if (use[i] > 0) {
            num = bin(use[i]);
            counts = count(num);
            m += counts;
            for (j = 0; j < counts; j++) {
                *(++newvalue) = value[i] * pow(2, j);
                *(++newweight) = weight[i] * pow(2, j);
            }
        } else {
            m++;
            *(++newvalue) = value[i];
            *(++newweight) = weight[i];
        }
    }
    *n = m;
    return 1;
}//0下标都为0

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


int compare(int *dp, int *weight, int *value, int n, int m) {
    int i, j, temp, k;
    for (i = 1; i <= n; i++) {
        for (j = m; j > 0; j--) {
            if (j >= weight[i]) {
                dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
            }
        }
    }
}

int news(int *weight, int *value, int *user, int n) {
    int i;
    for (i = 1; i <= n; i++) {
        scanf("%d%d%d", weight + i, value + i, user + i); //先重量再价值最后个数
    }
}


int main() {
    int dp[N] = {0}, value[N] = {0}, weight[N] = {0}, newvalue[N] = {0}, newweight[N] = {0}, use[N] = {0};
    int m, n;
    printf("先写物品数量后写背包大小\n");
    scanf("%d%d", &n, &m); //m为背包大小n为物品数量
    news(weight, value, use, n);
    distract(value, weight, use, newvalue, newweight, &n);
    compare(dp, newweight, newvalue, n, m);
    printf("new:");
    print(newvalue, n);
    print(newweight, n);
    printf("\n\n\n\n\n\n\n\n\n\n");
    printf("dp;\n");
    print(dp, m);
    printf("max=%d", dp[m]);
}

参考GPT和自己的思路:在你的代码中,出现了一个问题:

void print(int *p, int n) {
    int i;
    for (i = 0; i <= n; i++) {
        printf("%d\t", p[i]);
    }
    printf("\n");
}

在这个函数中,你应该使用小于等于号,而不是仅仅是小于号。因为数组的下标是从0开始的,所以在循环时应该循环到n-1的位置,而不是n的位置。修改后的代码如下:

void print(int *p, int n) {
    int i;
    for (i = 0; i < n; i++) {    // 修改这一行
        printf("%d\t", p[i]);
    }
    printf("\n");
}

这个问题应该就是你所遇到的 "出问题了" 的问题。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^