luoguP1858 多人背包

题目链接

分析:
首先要声明,题目有一些描述不准确的地方:

  • 背包一定要恰好装满
  • 不剔除相同数值的解

这是一道01背包K优解的问题
唯一的不同就是:背包必须装满
实际上这个问题也非常好解决:
如果我们不要求装满,取的是最大值,那么f的初始值就是0
如果要求装满,那么f的初始值就是-INF,其中f[0]=0

怎么理解呢:
初始化的f数组实际上就是在没有任何物品可以放入背包时的合法状态。
如果要求背包恰好装满,那么此时只有容量为0的背包可能被价值为0的nothing“恰好装满”
其它容量的背包均没有合法的解,属于未定义的状态,它们的值就都应该是-∞了。
如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不装”
这个解的价值为0,所以初始时状态的值也就全部为 0了

//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;

int f[5005][55],a[55],b[55];
int w[203],v[203];
int n,m,K;

int main()
{
    scanf("%d%d%d",&K,&m,&n);
    for (int i=1;i<=n;i++) scanf("%d%d",&w[i],&v[i]);
    memset(f,128,sizeof(f));         //注意初始化

    int i,j,p;
    f[0][1]=0;                       //注意初始化
    for (i=1;i<=n;i++)
    {
        for (j=m;j>=w[i];j--)
        {
            for (p=1;p<=K;p++)
            {
                a[p]=f[j][p];
                b[p]=f[j-w[i]][p]+v[i];
            }
            a[K+1]=b[K+1]=-1;
            int x,y,z;
            x=y=z=1;
            while (z<=K&&(a[x]!=-1||b[y]!=-1))
            {
                if (a[x]>b[y])
                   f[j][z]=a[x],x++;
                else f[j][z]=b[y],y++;
                z++;              //不剔除重复解
            }
        }
    }

    int ans=0;
    for (int i=1;i<=K;i++) ans+=f[m][i];
    printf("%d\n",ans);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值