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;
}