饭卡- HDU - 2546(01背包)

01背包问题求解思路

  ①、确认子问题和状态 
  01背包问题需要求解的就是,为了体积V的背包中物体总价值最大化,NN件物品中第ii件应该放入背包中吗?(其中每个物品最多只能放一件) 
  为此,我们定义一个二维数组,其中每个元素代表一个状态,即前ii个物体中若干个放入体积为VV背包中最大价值。数组为:f[N][V]f[N][V],其中fijfij表示前ii件中若干个物品放入体积为jj的背包中的最大价值。 
  ②、初始状态 
  初始状态为f[0][0−V]f[0][0−V]和f[0−N][0]f[0−N][0]都为0,前者表示前0个物品(也就是空物品)无论装入多大的包中总价值都为0,后者表示体积为0的背包啥价值的物品都装不进去。 

if (背包体积j小于物品i的体积)
    f[i][j] = f[i-1][j] //背包装不下第i个物体,目前只能靠前i-1个物体装包
else
    f[i][j] = max(f[i-1][j], f[i-1][j-Vi] + Wi)

最后一句的意思就是根据“为了体积V的背包中物体总价值最大化,NN件物品中第ii件应该放入背包中吗?”转化而来的。ViVi表示第ii件物体的体积,WiWi表示第ii件物品的价值。这样f[i-1][j]代表的就是不将这件物品放入背包,而f[i-1][j-Vi] + Wi则是代表将第i件放入背包之后的总价值,比较两者的价值,得出最大的价值存入现在的背包之。

我们做的转化就是,把除了最大菜价之外,其他的菜价装入一个sum-5 的背包里,看最大能装多少。

理论:http://www.cnblogs.com/fancy-itlife/p/4393213.html

首先看第一个条件—最优子结构。最大的装入量一定是如果装入第i个或者不装入第i个的两个选择之一。

第二个条件—子问题重叠。当完成一个阶段比如装第i个,我下面做的是对i-1个进行抉择,你可以发现跟前面的问题一样,装还是不装两个选择之一。这就是所谓的子问题重叠。

#include<bits/stdc++.h>
using namespace std;
#define maxn 1005
int a[maxn],dp[maxn];
int main()
{
    int n,v;
    while(cin>>n)
    {
        memset(dp,0,sizeof(dp));
        if(!n)
            break;
        for(int i=0; i<n; i++)
            cin>>a[i];
        cin>>v;
        if(v<5)
        {
            cout<<v<<endl;
            continue;
        }
        sort(a,a+n);
        for(int i=0; i<n-1; i++)
            for(int j=v-5; j>=a[i]; j--)
                dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
        cout<<v-dp[v-5]-a[n-1]<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值