#include<stdio.h>
//物品的种类数组的大小
#define zl1 100
//返回即是最大价值
int dfs(int w[] , int v[] , int NUM , int i , int num , int k)
{
//思考,存入背包问题有哪些情况
//第一个就是看容量和背包是否为0
//第二就是选择与不选择的情况
//在这里就要设置一个区分选择和不选择的判定,那就是最基础的原则某个物品的容量不能大于背包的总容量
//然后如果是不选择,那么直接下一个判定是否存入背包
//如果选择,那么也要分为两种情况,那就是价值和容量的大小是否为最大值,因为我需要最优方案,求最大的总价值
//假如是0种物品或者背包容量为0,那就价值那么就是0
//从当前所剩余的最后一个物品开始向前逐个判断是否要添加到背包中去
//某个物品的容量不能大于背包的总容量
if (i < NUM)
{
if(w[i] <=num )
{
//如果不选择,那么在这种情况的最优解为f(n-1,C) 只选择前n-1件物品
if (w[i] > num) //物品容量大于剩余的容量
{
//flag[i] = 0; //不选择那么就在这里做一个标记
return dfs(w, v, NUM, i + 1, num, k); //继续往前判断 ,其他不变
}
//当物品容量小于总容量时,也分为两个情况,就是这个物品放入还是不放入
else
{
int m1 = dfs(w, v, NUM, i + 1, num, k);//不选择物品i的情况下的最优解
int m2 = dfs(w, v, NUM, i + 1, num - w[i], k + v[i]); //如果选择,那就价值求和,容量减少
//比较一下
//返回选择物品i和不选择物品i中最优解大的一个
if (m1 > m2 )
{
return m1;
}
//被存入
else
{
return m2;
}
}
}
}
return k;
}
int main()
{
//这里直接弄一个,不好自己弄一个变长数组就固定了,弄一个结构体数组吧
//int w[4] = { 1 , 3 , 3 , 6 }; //所占容量
//int v[4] = { 3 , 5 , 1 , 7 }; //价值
//弄一个自己输入的数组
int w[zl1] = { 0 };
int v[zl1] = { 0 };
int zl = 0;//物品种类
printf("请输入物品有几个种类 : \n");
scanf("%d", &zl);
//printf("请分别输入物品的所占容量和价值(空格隔开) \n");
//依据物品种类给数组输入内容
for (int i = 0; i < zl; i++)
{
printf("请输入第 %d 类物品的所占容量和价值 (空格隔开) \n",i+1);
scanf("%d", &w[i]);
scanf("%d", &v[i]);
}
int i = 0; //从0位置开始
//int NUM = 4; //物品种类
int num = 0; //背包剩余容量
int k = 0; //目前总价值
printf("请输入背包的体积大小 : ");
scanf("%d", &num);
int maxjz = dfs(w,v,zl, i ,num ,k);
printf("最优方案的总价值为 : %d \n", maxjz);
return 0;
}
01背包问题,动态规划,递归解决
于 2023-12-09 16:53:04 首次发布