牛牛的背包问题—网易互联网2018笔试

牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为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

输出例子1:
8

解法一:
全组合,暴力破解。(会出现超时,只能通过80%)

#include 
#include 
#include 
#include 
#include 
#include
#define LL long long //注意数据超过整数的问题,所以需要使用long long
using namespace std;

void combination(vector<int> vec, LL bag, int& ans) { //全组合
    if (vec.empty())
        return;
    int n = vec.size();
    int nBit = 1 << n;
    for (int i = 1; i < nBit; i++) {
        LL temp = bag;
        for (int j = 0; j <= (log2(i)+1); j++) {
            if (i << (31 - j) >> 31 == -1)  //if条件判断i中第j位是否为1。
                temp = temp - vec[j];
        }
        if (temp >= 0)
            ans++;
    }
    return;
}

int main() {
    //  string str = "aabc";
    int num;
    LL bag;
    cin >> num >> bag;
    vector<int> vec(num, 0);
    for (int i = 0; i < num; i++)
        cin >> vec[i];
    LL count = bag;
    sort(vec.begin(), vec.end());
    for (int i = 0; i < num; i++) {
        count -= vec[i];
    }
    int ans = 1;
    if (count >= 0) {  //所有零食总体积小于背包容量时。
        ans += (pow(2, num) - 1);
    }
    else
        combination(vec, bag, ans);
    cout << ans << endl;
    return 0;
}

方法二:
先对所有数字排序,然后对排序的数从小到大依次装入背包,计算最多能装入的个数 i 。然后按照转入背包的个数进行计算结果,即先计算装入1个的情况,然后计算转入2个…..直到计算装入i个。(100%通过)

#include 
#include 
#include 
#include 
#include 
using namespace std;

void findCombination(const int n, int& count, int size, const int order, const int bag, const vector<int> vec){ //装入n个的全组合数
    if (size == n){
        if (bag >= 0)
            count++;
        return;
    }
    for (int i = order; i// iterative component
        if (vec[i]>bag) return;
        findCombination(n, count, size+1, i + 1, bag - vec[i], vec); // recursive componenet
    }
}
int main(){
    int num,bag;
    cin >> num >> bag;
    vector<int> vec(num, 0);
    for (int i = 0; i < num; i++)
        cin >> vec[i];
    int count = bag;
    int i;
    int ans = 1;
    sort(vec.begin(), vec.end());
    for ( i = 0; i < num; i++) {
        if (vec[i]>count)
            break;
        else
            count -= vec[i];
    }
    if (i == num)
        ans = pow(2, num);
    else
        for (int j = 1; j <= i; j++){
            int num = 0;
            findCombination(j, num, 0, 0, bag, vec);
            ans += num;
        }
    cout << ans << endl;
    return 0;
}

你可能感兴趣的:(数据结构和算法)