多重揹包二進位制優化(POJ1276)
阿新 • • 發佈:2019-01-22
主要是記錄一下對於揹包問題的二進位制優化方法
1.多重揹包使用二進位制優化後轉化為01揹包問題
#include <iostream> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <string> #include <bitset> #include <map> #include <cstring> using namespace std; int dp[100005]; int main() { int W; while(scanf("%d",&W) != EOF) { memset(dp, 0, sizeof(dp)); int n; scanf("%d", &n); for(int i = 0; i < n; ++i) { int v, c; scanf("%d%d", &c, &v); int a = 1; while(c > a) { c -= a; for(int j = W; j >= a * v; --j) dp[j] = max(dp[j], dp[j - a * v] + a * v); a *= 2; } for(int j = W; j >= c * v; --j) dp[j] = max(dp[j], dp[j - c * v] + c * v); } printf("%d\n", dp[W]); } return 0; }
2.多重揹包問題轉化為01揹包和完全揹包問題(看c*v是否超過揹包的容量)
#include <iostream> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <string> #include <bitset> #include <map> #include <cstring> using namespace std; int dp[100005]; int main() { int W; while(scanf("%d",&W) != EOF) { memset(dp, 0, sizeof(dp)); int n; scanf("%d", &n); for(int i = 0; i < n; ++i) { int v, c; scanf("%d%d", &c, &v); if(c * v >= W) { for(int j = v; j <= W; ++j) dp[j] = max(dp[j], dp[j - v] + v); } else { int a = 1; while(c > a) { c -= a; for(int j = W; j >= a * v; --j) dp[j] = max(dp[j], dp[j - a * v] + a * v); a *= 2; } for(int j = W; j >= c * v; --j) dp[j] = max(dp[j], dp[j - c * v] + c * v); } } printf("%d\n", dp[W]); } return 0; }
另外記錄一下另一個同時使用01揹包和完全揹包的寫法
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include <set> #include <algorithm> typedef long long ll; using namespace std; const int N=5e4+7; int dp[N]={0}; int v; void com(int w,int p)//完全揹包 { for(int j=w;j<=v;j++) dp[j]=max(dp[j],dp[j-w]+p); } void zero(int w,int p)//01揹包 { for(int j=v;j>=w;j--) dp[j]=max(dp[j],dp[j-w]+p); } void add(int w,int p,int c) { if(c*w>=v)//完全揹包 { com(w,p); return ; } int a=1; while(c>a)//01揹包二進位制優化 將數字變為二進位制相加,打包 { c-=a; zero(w*a,p*a); a*=2; } zero(w*c,p*c); } int main() { int n; int w,p,c; scanf("%d%d",&n,&v); for(int i=0;i<n;i++) { scanf("%d%d%d",&w,&p,&c); add(w,p,c); } printf("%d\n",dp[v]); }