动态规划之0/1背包问题

看懂表格怎么来的,然后自己做一遍。就是你想知道的

M:10  n:3   w  p

                  3   4

                  4   5

                  5   6

表格中的数表示当前最大收益:行:从0——10 表示背包容量     列:0——2,表示物品0,物品1,物品2

 012345678910
000044444444
100045559999
200045669101111

void Init()
{  int i;
   cin>>n>>w;
   w=new int[n];
    p=new int[n];
   for(i=0;i<n;i++)
   {
        cin>>w[i]>>p[i];
   }
   a=new int*[n+1];
   for(i=0;i<n+1;i++)
   {
        a[i]=new int[w+1];
    }
}
int Package0_1()
{
    int i,j;
    for(i=0;i<n+1;i++)
    {
       a[i][0]=0;
     }
     for(i=0;i<w+1;i++)
     {
         a[0][i]=0;
      }
    for(i=1;i<=n;i++)
    {
       for(j=1;j<=n;j++)
        {
           if(j>=w[i-1])
            {
               if(p[i-1]+a[i-1][j-w[i-1]]>a[i-1][j])
                {
                   a[i][j]=p[i-1]+a[i-1][j-w[i-1]];
                 }
                else
                   {
                      a[i][j]=a[i-1][j];
                    }
              }
              else
              {
                  a[i][j]=a[i-1][j];
               }
         }
     }
     return a[n][m];
 }
#include"iostream"
using namespace std;
int **a;
int n,w;
int *w,*p;
 int main()
{
Init();
cout<<Package0_1()<<endl;
}



用二维数组实现0/1背包的动态规划是为了便于理解,但是很消耗内存。所以可以进行优化,改为一维数组。

思路:在计算中每次只用到二维数组中的相邻两行,所以在一次计算后把结果保存在temp数组中,下一次计算时只需访问上一次保存的数组即可。

如下:



//此处a为一维数组
int Package0_1()
{
    int i,j,k;
    int *temp=new int[w+1];
    for(k=0;k<w+1;k++)   temp[k]=0;
    i=1;
    while(i<=n)
    {
         j=w[i-1];
         for(k=0;k<j;k++)   a[k]=temp[k];
         for(;j<=w;j++)
         {
              if(p[i-1]+temp[j-w[i-1]]>temp[j])
              {
                    a[j]=p[i-1]+temp[j-w[i-1]];
               }
              else
                {
                    a[j]=temp[j];
                }
          }
    }
     return a[w];
 }





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值