多重背包+二进制优化
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #define maxn 100000+10 using namespace std; int dp[maxn],n,k; int v[101],w[101],V; void zero(int cost) { for(int i=V;i>=cost;i--) dp[i]=max(dp[i],dp[i-cost]+cost); } void complet(int cost) { for(int i=cost;i<=V;i++) dp[i]=max(dp[i],dp[i-cost]+cost); } void multi(int cost,int amount) { if(cost * amount>=V) { complet(cost); return ; } int k=1; while(k<amount) { zero(k*cost); amount-=k; k<<=1; } zero(amount*cost); } int main() { while(~scanf("%d%d",&V,&n)) { for(int i=0;i<n;i++) scanf("%d%d",&w[i],&v[i]); memset(dp,0,sizeof(dp)); dp[0]=0; for(int i=0;i<n;i++) multi(v[i],w[i]); printf("%d ",dp[V]); } return 0; }