逃亡的准备这道题怎么做,给代码(C++)


在《Harry Potter and the Deathly Hallows》中,Harry Potter他们一起逃亡,现在有许多的东西要放到赫敏的包里面,但是包的大小有限,所以我们只能够在里面放入非常重要的物品,现在给出该种物品的数量、体积、价值的数值,希望你能够算出怎样能使背包的价值最大的组合方式,并且输出这个数值,赫敏会非常地感谢你。

【输入文件】(hallows.in)

(1)第一行有2个整数,物品种数n和背包装载体积v。

(22行到i+1行每行3个整数,为第i种物品的数量m、体积w、价值s。.

【输出文件】(hallows.out)

    输出文件hallows.out仅包含一个整数,即为能拿到的最大的物品价值总和。

【输入样例】

2 10

3 4 3

2 2 5

【输出样例】

13

【注释】

选第一种一个,第二种两个。

结果为3*1+5*2=13

【数据规模】

对于30%的数据

1<=v<=500

1<=n<=2000

1<=m<=10

1<=w<=20

1<=s<=100

 

对于100%的数据

1<=v<=500

1<=n<=2000

1<=m<=5000

1<=w<=20

1<=s<=100

可以参考这个,有思路有代码: SSL_1236【逃亡的准备】_zhanglili1597895的博客-CSDN博客 逃亡的准备题目在《Harry Potter and the Deathly Hallows》中,Harry Potter他们一起逃亡,现在有许多的东西要放到赫敏的包里面,但是包的大小有限,所以我们只能够在里面放入非常重要的物品,现在给出该种物品的数量、体积、价值的数值,希望你能够算出怎样能使背包的价值最大的组合方式,并且输出这个数值,赫敏会非常地感谢你。Input(1)第一行有2个整数,物品种数n和背包装载体积v。(2)2行到n+1行每行3个整数,为第i种物品的数量m、体积w、价值s。Outpu https://blog.csdn.net/zhanglili1597895/article/details/111292863

#include<iostream>
#include<cstdio>
using namespace std;
int q,dp[510],x,y,z,n,s=0;
void ddp(int xx,int yy)//即时背包
{
    for(int i=n;i>=xx;i--)dp[i]=max(dp[i],dp[i-xx]+yy);
    return;
}
int main()
{
    scanf("%d%d",&q,&n);
    while(q--)
    {
        scanf("%d%d%d",&x,&y,&z);
        s=1;//位的价值
        while(x>=s)//二进制拆分
        {
            ddp(s*y,s*z);
            x-=s;
            s*=2;
        }
        if(x!=0)ddp(x*y,x*z);
    }
    printf("%d",dp[n]);
    return 0;
}


img

如有帮助请采纳

这道题是一个有限背包,我们可以按照有限背包的板子写:

#include<bits/stdc++.h>
using namespace std;
int n,v;
struct bag {
    int m,w,s;
} a[1000001];
int dp[1000001];
int main() {
    scanf("%d %d" ,&n ,&v);
    for(int i = 1; i <= n; i++) {
        scanf("%d %d %d" ,&a[i].m,&a[i].w,&a[i].s);
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= a[i].m; j++) {
            for(int k = v; k >= a[i].w; k--) {
                dp[k] = max(dp[k],dp[k - a[i].w] + a[i].s);
            }
        }
    }
    printf("%d" ,dp[v]);
    return 0;
}
但是这样做复杂度是有亿点点高的,高到可以卡掉三个点,所以我们需要用到二进制优化来帮我们降低复杂度:

什么是二进制优化呢?
顾名思义,我们把同种每2n的物品放在一起,当作一件物品(其价值和体积需要对应累加),处理完后当作0 1背包来做即可。
比如7个物品:
7 = 1 + 2 + 4.
而有意思的是,124正好可以凑出从17所有的整数,因此我们这么做在dp的时候是不会少情况的(具体证明我也不会)。
接下来就是二进制优化之后的代码:

#include<bits/stdc++.h>
using namespace std;
int ans = 0,nn = 0,t;
int dp[2001]= { },j,w[100001],s[100001];
int a[100001],b[1000001];
int m[100001];
int n,v;
int cnt = 0;
int main() {
    scanf("%d %d" ,&n,&v);
    for(int i = 1;i <= n; i++){
        scanf("%d %d %d" ,&m[i],&a[i],&b[i]);
    }
    for(int i = 1;i <= n; i++){
        for(int j = 1;j <= m[i];j<<=1){
            w[++cnt] = j * a[i];
            s[cnt] = j * b[i];
            m[i] = m[i] - j;
        }
        if(m[i] > 0){
            s[++cnt] = m[i] * b[i];
            w[cnt] = m[i] * a[i];
        }
    }
    for(int i = 1; i <= cnt; i++) {
        for(int k = v; k >= w[i]; k--) {
            dp[k] = max(dp[k],dp[k - w[i]] + s[i]);   //处理完后所有的都要换成新数组
        }
    }
    printf("%d" ,dp[v]);
        return 0;
}