2602 )和完全揹包(POJ
阿新 • • 發佈:2019-02-07
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; }