自己复习用 1.单调队列法 详见《挑战》p340 然后我其实不懂为什么在deq[s]==j-m[i]时去掉队首,过几天懂了我来更新,如果你知道的话请告诉我qq2298763866
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <algorithm> #include <queue> using namespace std; const int maxn=200; const int maxm=10100; const int maxw=10100; int n,wgh; int w[maxn]; int v[maxn]; int m[maxn]; int dp[maxn+maxm]; int main() { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d%d",&w[i],&v[i],&m[i]); } scanf("%d",&wgh); int deq[maxn]; int deqv[maxn]; int s=0; int t=0; for(int i=0;i<n;i++) { for(int a=0;a<w[i];a++) { s=0; t=-1; for(int j=0;j*w[i]+a<=wgh;j++) { int b=dp[j*w[i]+a]-j*v[i];//加入单调队列的是b值 while(s<=t && deqv[t]<=b) { t--; } t++; deq[t]=j; deqv[t]=b; dp[j*w[i]+a]=deqv[s]+j*v[i]; // if(deq[s]==j-m[i]) { s++; } // } } } printf("%d\n",dp[wgh]); return 0; }2.二进制背包 9讲上有 不过自己写还是第一次
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <algorithm> #include <queue> using namespace std; const int maxn=200; const int maxm=10100; const int maxw=10100; int n,wgh; int w[maxn]; int v[maxn]; int m[maxn]; int dp[maxn+maxm]; int main() { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d%d",&w[i],&v[i],&m[i]); } scanf("%d",&wgh); int num=0; for(int i=0;i<n;i++) { num=m[i]; for(int j=1;num>0;j<<=1) { int mul=min(j,num); for(int k=wgh;k>=w[i]*mul;k--) { dp[k]=max(dp[k],dp[k-w[i]*mul]+mul*v[i]); } num-=mul; } } printf("%d\n",dp[wgh]); return 0; }理由等我过几天懂了再来更