动态规划解背包问题

///////////动态规划解背包问题////////////
动态规划:对大问题进行小问题分解
 情况1:物品1放入背包,对应子问题:背包容量减少物品1体积后,对剩余物品求解
 情况2:物品1不放入背包,对应子问题:背包容量不变,对剩余物品求解。
 
使用结构体:
 item{int value;int volume;} //保存物品的价值与体积
 memory(int IfIn,valueSum,volumeSum) //保存结果
 
函数说明: DynamicToPackage (item ite[],int save[][]) 
 输入: item ite[] //节点信息
   int save[][] //保存结果二维表
 输出: 返回结果二维表save
 
算法简析:
 for (i : each node)    
  for (j : maxVol)   //从0开始对每个物品进行各种剩余背包容量情况计算
   if (node.vol<=j)  //如果当前节点可以放入当前背包剩余容量
    if (value up)    //如果当前物品放入背包总价值增加
     node in    //记录节点放入背包信息
    else    //如果当前物品放入背包总价值不增加
     node no in    //记录节点不放入背包信息
   else      //如果当前节点不可以放入当前背包剩余容量
    node no in     //记录节点不放入背包信息
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#define MAX 3   //物品数
#define maxVol 10    //背包容量
//#define MAX 6   //物品数
//#define maxVol 21    //背包容量
typedef struct
{
    int value; //物品价值
    int volume; //物品体积
} item;
typedef struct
{
 bool IfIn;  //是否放入背包
 int valueSum; //背包内价值总和
 int volumeSum; //背包内体积总和
} memory;
void makeItem (int value[],int volume[],item ite[]);//将物品信息保存到结构体
void print (memory save[MAX][maxVol+1],item ite[]); //输出结果

void DynamicToPackage (item ite[],memory save[MAX][maxVol+1]);
///////////////////////////////////////////
int main ()
{
 //int value[MAX]  = {20,15,15,10,30,60}; //物品价值
    //int volume[MAX] = {3,6,5,2,4,8}; //物品体积
    int value[MAX]  = {4,5,6}; //物品价值
    int volume[MAX] = {3,4,5}; //物品体积
   
 item ite[MAX]; //保存物品信息
 memory save[MAX][maxVol+1];  //保存图表
 
    makeItem (value,volume,ite);//将物品信息保存到结构体
 DynamicToPackage (ite,save);
 print (save,ite);
 return 0;
}
//将物品信息保存到结构体
void makeItem (int value[],int volume[],item ite[])
{
    int i;
    for (i=0; i<MAX; i++)
    {
        ite[i].value = value[i];
        ite[i].volume = volume[i];
    }
}
//输出结果
void print (memory save[MAX][maxVol+1],item ite[])
{
 int i,j;
 printf ("生成的表(是否放入背包,背包内物品总体积,背包内物品总价值):\n");
 for (i=0; i<=maxVol; i++)
 {
  for (j=0; j<MAX; j++)
   printf ("(%d,%d,%d) ",save[j][i].IfIn,save[j][i].volumeSum,save[j][i].valueSum);
  printf ("\n");
 }
 printf ("背包容量为:%d\n",maxVol);
 printf ("放入背包的物品组成为(价值,体积):");
 for (i=MAX-1,j=maxVol; i>= 0; i--)
 {
  if (save[i][j].IfIn)
  {
   printf ("(%d,%d) ",ite[i].value,ite[i].volume);
   j = j - ite[i].volume;
  }
 } 
 printf ("\n总价值为:%d  总使用体积为:%d\n",save[MAX-1][maxVol].valueSum,save[MAX-1][maxVol].volumeSum);
}

void DynamicToPackage (item ite[],memory save[MAX][maxVol+1])
{
 int i,j; //i--节点  j--剩余背包容量
 for (j=0; j<=maxVol; j++)
 {
  if (ite[0].volume <= j)
  {
   save[0][j].valueSum = ite[0].value;
   save[0][j].IfIn = true;
   save[0][j].volumeSum = ite[0].volume;
  }   
  else
  {
   save[0][j].valueSum = 0;
   save[0][j].IfIn = false;
   save[0][j].volumeSum = 0;
  } 
 }
 for (i=1; i<MAX; i++)  //对每个节点进行计算
 {
  for (j=0; j<=maxVol; j++)  //从0开始对每个物品进行各种剩余背包容量情况计算
  {
   if (ite[i].volume <= j) //如果当前节点可以放入当前背包剩余容量
   {//如果 减去当前物品体积下前面的最大价值 + 当前物品价值  >=  前面物品在体积j的最大价值
    if (save[i-1][j-ite[i].volume].valueSum+ite[i].value >= save[i-1][j].valueSum)
    {
     save[i][j].IfIn = true;
     save[i][j].valueSum = save[i-1][j-ite[i].volume].valueSum + ite[i].value;
     save[i][j].volumeSum = save[i-1][j-ite[i].volume].volumeSum + ite[i].volume;
    }
    else
    {
     save[i][j].IfIn = false;
     save[i][j].valueSum = save[i-1][j].valueSum;
     save[i][j].volumeSum =  save[i-1][j].volumeSum;
    }
   }
   else //如果当前节点不可以放入当前背包剩余容量
   {
    save[i][j].IfIn = false;
    save[i][j].valueSum = save[i-1][j].valueSum;
    save[i][j].volumeSum =  save[i-1][j].volumeSum;
   }
  }
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值