01背包(HDU - 2602  )和完全背包(POJ - 1384  )体积要求区别

POJ - 1384  完全背包问题,体积要求有点区别,要求猪是100斤就只能是100斤(必须装满)

然后我想起来另一道题HDU - 2602 ,这是经典的01背包裸题了,求给定最大体积下最大为多少价值(允许不装满)。

 

括号就是差别,当然,不是说01一定是允许不装满,完全背包一定是必须装满。这种条件差别的解决涉及到另外一个问题,memset的初始化。

确定条件:dp方程肯定是没问题的,要在上面进行修改。

问题:如何知道装不满?

答:立flag啊,flag倒了就说明没装满。

问:咋立flag?

答:没装满的标为false,装满的标为true。

实际操作中我们不需要再开一个数组,我们可以通过处理dp方程来解决,装满的体现一个数值,没装满的位置体现为INF,根据dp的思想我们可以确定,dp[j] = min(dp[j-wei[i]]+val[i],dp[j]);如果min里面俩位置都没装满,肯定都>=INF,可以体现此时没装满。

得出结论:其实和啥背包没关系,主要是初始化问题。

附上代码:

 

/*POJ - 1384*/

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int N,M;
#define INF 0x3f3f3f3f
const int maxn = 1003;
int dp[maxn*10];
int val[maxn],wei[maxn];
int main()
{
    ios::sync_with_stdio(false);
    int n,all_wei;
    cin>>n;
    while(n--)
    {
        memset(dp,INF,sizeof(dp));
        dp[0] = 0;
        int a,b;
        cin>>a>>b;
        all_wei = b-a;
        int t;
        cin>>t;
        for(int i=0;i<t;i++)
            cin>>val[i]>>wei[i];
        for(int i=0;i<t;i++)
        {
            for(int j=wei[i];j<=all_wei;j++)
            {
                dp[j] = min(dp[j-wei[i]]+val[i],dp[j]);
            }
        }
        if(all_wei < 0 || dp[all_wei] == INF)
            cout<<"This is impossible."<<endl;
        else cout<<"The minimum amount of money in the piggy-bank is "<<dp[all_wei]<<"."<<endl;
    }
    return 0;
}
/*HDU - 2602*/

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll ;
const int maxn = 1003;
int t;
int n,v;
int val[maxn];
int wei[maxn];
int dp[1003];
int main()
{
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        cin>>n>>v;
        for(int i=0;i<n;i++)
            cin>>val[i];
        for(int i=0;i<n;i++)
            cin>>wei[i];
        for(int i=0;i<n;i++)
        {
            for(int j = v;j>=wei[i];j--)
            {
                dp[j] = max(dp[j-wei[i]]+val[i],dp[j]);
            }
        }
        cout<<dp[v]<<endl;
    }
    return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值