--- title: "最大价值" created: 2025-11-28 tags: - 算法 --- # 最大价值 ## 题目 [最大价值](https://www.acwing.com/problem/content/description/4880/) ![[image-d3e01682.png]] ## 思路分析 第0种物品可以取无限次 第1-m种物品可以取l/h次 所以可以把问题变成 完全背包+多重背包的混合背包问题 也可以直接对0物品进行特判 做多重背包问题 因为数据范围较小 暴力的多重背包也能过 但还是习惯性的写二进制优化吧 ## 代码实现 ```cpp #include using namespace std; const int N=1010; int s[N],v[N],w[N]; int f[N]; int n,m; int main() { cin>>n>>m>>v[0]>>w[0]; for(int i=1;i<=m;i++){ int l,h; cin>>l>>h>>v[i]>>w[i]; s[i]=l/h; } //v[0]的完全背包问题 for(int i=v[0];i<=n;i++) f[i]=f[i-v[0]]+w[0]; //1-m的多重背包问题暴力做法 for(int i=1;i<=m;i++){ for(int j=n;j>=0;j--){ for(int k=1;k<=s[i] && k*v[i]<=j;k++){ f[j]=max(f[j],f[j-k*v[i]]+k*w[i]); } } } cout< using namespace std; const int N=1010; int s[N],v[N],w[N]; int f[N]; int cnt; int n,m; int main() { cin>>n>>m>>v[0]>>w[0]; for(int i=1;i<=m;i++){ int l,h,vi,wi; cin>>l>>h>>vi>>wi; int k=1,s=l/h; while(k<=s){ cnt++; v[cnt]=vi*k; w[cnt]=wi*k; s-=k; k*=2; } if(s){ cnt++; v[cnt]=vi*s; w[cnt]=wi*s; } } //v[0]的完全背包问题 for(int i=v[0];i<=n;i++) f[i]=f[i-v[0]]+w[0]; //1-m的多重背包问题 01做法 for(int i=1;i<=cnt;i++){ for(int j=n;j>=v[i];j--){ f[j]=max(f[j],f[j-v[i]]+w[i]); } } cout<