【网易】牛牛的背包问题

题目描述
牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为w。
牛牛家里一共有n袋零食, 第i袋零食体积为v[i]。
牛牛想知道在总体积不超过背包容量的情况下,他一共有多少种零食放法(总体积为0也算一种放法)。
输入描述:
输入包括两行
第一行为两个正整数n和w(1 <= n <= 30, 1 <= w <= 2 * 10^9),表示零食的数量和背包的容量。
第二行n个正整数v[i](0 <= v[i] <= 10^9),表示每袋零食的体积。
输出描述:
输出一个正整数, 表示牛牛一共有多少种零食放法。

示例1
输入
3 10
1 2 4
输出
8

说明
三种零食总体积小于10,于是每种零食有放入和不放入两种情况,一共有222 = 8种情况。

思路:
设state(i,w)表示i个零食放入背包小于等于W的个数,把state(i,w)分解,可以分解为两个情况:
1、是第i个不放入时,前i-1个零食放入背包小于等于W的个数即state(i-1,w);
2、是在第i个放入的情况下,前i-1个零食放入背包体积小于等于W-v[i]的个数即state(i-1,w-v[i]);

即 state(i,w) = state(i-1,w) + state(i-1,w-v[i])

边界条件:i = 1时,state(1,w1) 此时如果w1 >0 且v[1]<=w1,state(1,w1) = 2,即有可放入和不放入两种;
i = 1 时,swate(1,w1)此时如果w1 >0且v[1] > w1,state(1,w1)=1,即只有不放入一种;
如果state(i,w)中出现w<=0,则state(i,w)=0;
例子:零食体积1 2 4,w=10
则 state(3,10) = state(2,10) + state(2,6)
= state(1,10) + state(1,8) + state(1,6) + state(1,4)
= 2 + 2 + 2 + 2 = 8

注意,如果直接递归穷举会超时,因此我们判断所有物品体积和是否小于书包体积,是的话直接输出2^n,另外pow函数到不了2的30次方,因此我们单独计算power

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int func(int i,int w,vector<int64_t>& food)
{
    if(w<=0) return 0;
    if(i==1)
    {
        if(food[i]<=w) return 2;
        else return 1;
    }
    return func(i-1,w,food)+func(i-1,w-food[i],food);
}

int main()
{
    int64_t n,w,sum=0,power=1;
    cin>>n>>w;
    vector<int64_t> food(n+1);
    for(int i=1;i<n+1;++i)
    {
        cin>>food[i];
        sum+=food[i];
        power*=2;
    }
    if(sum<=w) cout<<power;
    else cout<<func(n,w,food);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值