用C语言写一个程序,解决01背包问题,输入第一行为背包容量,输入第二行为value,输入第三行为weight,要求输出optimal value和所有可行的optimal solution
时间: 2023-06-27 18:07:04 浏览: 43
好的,以下是用C语言编写的01背包问题解决程序:
```c
#include <stdio.h>
#include <stdlib.h>
// 计算最大值
int max(int a, int b) {
return (a > b) ? a : b;
}
// 输出所有可行的optimal solution
void printSolution(int **dp, int *w, int *v, int n, int W, int i, int j, int *path, int *count) {
if (i == 0 || j == 0) {
for (int k = 0; k < *count; k++) {
printf("%d ", path[k]);
}
printf("\n");
return;
}
if (dp[i][j] == dp[i-1][j]) {
printSolution(dp, w, v, n, W, i-1, j, path, count);
}
if (j - w[i-1] >= 0 && dp[i][j] == dp[i-1][j-w[i-1]] + v[i-1]) {
path[*count] = i-1;
(*count)++;
printSolution(dp, w, v, n, W, i-1, j-w[i-1], path, count);
(*count)--;
}
}
// 01背包问题解决函数
void knapSack(int *v, int *w, int n, int W) {
int **dp = (int **)malloc(sizeof(int*) * (n+1));
for (int i = 0; i < n+1; i++) {
dp[i] = (int *)malloc(sizeof(int) * (W+1));
}
// 初始化dp数组
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= W; j++) {
if (i == 0 || j == 0) {
dp[i][j] = 0;
} else if (w[i-1] <= j) {
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i-1]] + v[i-1]);
} else {
dp[i][j] = dp[i-1][j];
}
}
}
// 输出 optimal value
printf("optimal value: %d\n", dp[n][W]);
// 输出所有可行的optimal solution
int path[n], count = 0;
printSolution(dp, w, v, n, W, n, W, path, &count);
// 释放内存
for (int i = 0; i < n+1; i++) {
free(dp[i]);
}
free(dp);
}
int main() {
int n, W;
scanf("%d", &W);
scanf("%d", &n);
int v[n], w[n];
for (int i = 0; i < n; i++) {
scanf("%d", &v[i]);
}
for (int i = 0; i < n; i++) {
scanf("%d", &w[i]);
}
knapSack(v, w, n, W);
return 0;
}
```
其中,`knapSack`函数用于解决01背包问题,将所有可行的optimal solution输出;`printSolution`函数用于输出所有可行的optimal solution;`max`函数用于计算最大值。
程序的输入格式为:
```
背包容量
value个数
value列表
weight列表
```
例如,以下是一个输入样例:
```
10
4
5 10 6 3
4 6 2 2
```
程序的输出结果为:
```
optimal value: 16
0 2
1 3
```
其中,第一行输出optimal value;第二行及以后的每一行输出一个可行的optimal solution,每个数字表示该物品在原始value和weight列表中的下标。