您的位置:首页 > 其它

POJ - 3624 (01背包问题)(动态规划-滚动数组)

2018-03-02 16:55 573 查看
题意:
        往手镯上镶嵌宝石,手镯总重量有上限,要求手镯的总价值最大。
        本质就是一个01背包问题。

解题思路:
        下面开始分析01背包问题。

        动态规划问题主要是找到子问题,即一旦确定了第i个状态,就可以直接推出第i+1个状态。(有后效性)

以题目给出的数据举例:
  4 6 n m
① 1 4 w[i] v[i]
② 2 6
③ 3 12
④ 2 7设F[j]为背包剩余容积为j时背包所能达到的最大价值。(j <= m)
取①号物体时,如果j < 1,则F[0] = 0,如果j >= 1时,F[1]=F[2]=...=F[6]=4;
取②号物体时,如果j < 2,则F[1]保持不变,仍为4;
                       如果j >= 2,则可以选择取或者不取②号物体,因此F[j] = max(F[j],F[ j-w[i] ]+v[i]);(如下所示)
取:F[2] = F[ j-w[i] ]+v[i] = F[0]+v[2]=0+6=6;
       F[3] = F[ j-w[i] ]+v[i] = F[1]+v[2]=4+6=10;

       F[4] = F[ j-w[i] ]+v[i] = F[2]+v[2]=4+6=10;...F[5]=F[6]=10;

不取:F[1]=F[2]=...=F[6]=4;

因此F[j]=max(取,不取)=max(F[j],F[ j-w[i] ]+v[i]);

取③号物体...取④号物体,依次类推
下面是代码实现:#include <cstdio>
#include <algorithm>

using namespace std;

int w[3410],v[3410]; //记录各个物体的重量和价值
int f[12900]; //记录当背包剩余重量为j时的背包最大价值

int main()
{
int n,m;//n是个数,m是最大重量

scanf("%d%d",&n,&m);
for(int i = 0;i < n;i++)
{
scanf("%d%d",&w[i],&v[i]);
}
for(int i = 0;i < n;i++)
{
for(int j = m;j >= 1;j--)
{
if(j >= w[i])
{
f[j] = max(f[j],f[j-w[i]]+v[i]);//取还是不取
}
}
}
sort(f,f+m+1);
printf("%d\n",f[m]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划 01背包