网易2019实习生招聘笔试-牛牛的背包问题

时间限制:1秒

空间限制:32768K

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

如题,最容易想到的方法是位运算或者dfs枚举,分别取得了60%和80%的“优秀”成绩,先贴代码

#include 
#include 
#include 
#define LL long long
using namespace std;
LL n;
LL v,k;
LL a[33];
LL cnt=0;
int flag=1;
int main(){
    cin>>n>>v;
    for(LL i=0;i>a[i];
    }
    LL s=1<v){
                    break;
                }
            }
        }
        if(now_v<=v){
            //cout<
#include 
#include 
#include 
#define LL long long
using namespace std;
LL n;
LL v,k;
LL a[33];
LL cnt=0;
void dfs(int k,LL s){

    if(k==n){
        cnt+=1;
        return ;
    }
    if(s+a[k]<=v){
        dfs(k+1,s+a[k]);
    }
    dfs(k+1,s);
}
int main(){
    scanf("%lld%lld",&n,&v);
    for(LL i=0;i

显然2^30的复杂度是不被允许的,暴力枚举不可取,通过大神的点拨后想到将30分成两份,把我们能接受的前15个物品先进行第一次枚举搜索,然后再对剩下的物品进行第二次枚举搜索。把第二次枚举搜索出来的结果(至多2^15=32768个答案)存入数组并排序,枚举第一次搜出来的结果,计算出还剩下多少背包体积还能装,在第二次的结果中进行二分搜索,并把两次搜索的结果进行相乘(乘法原理)。再把所有的结果进行相加(加法原理),就是答案了。

#include 
#include 
#include 
#include 
#include 
using namespace std;
long long a[50];
int main()
{
    int n;
    long long m;
    cin>>n>>m;
    for(int i=0;i>a[i];
    if(n<20)
    {
        int ans=0;
        for(int i=0;i<1<mp;
    for(int i=0;i<(1<<15);++i)
    {
        long long weight=0;
        for(int j=0;j<15;++j)
            if((i&(1<m)
            continue;
        if(mp.find(weight)!=mp.end())
            mp[weight]++;
        else mp[weight]=1;
    }
    //cout<another;
    for(int i=0;i<(1<m)
            continue;
        if(another.find(weight)!=another.end())
            another[weight]++;
        else another[weight]=1;
    }
    vector >vec;
    for(map::iterator it=another.begin();it!=another.end();++it)
        vec.push_back(make_pair(it->first,it->second));
    for(int i=1;i::iterator it=mp.begin();it!=mp.end();++it)
    {
        long long p=m-(it->first);
        int q=lower_bound(vec.begin(),vec.end(),make_pair(p,0))-vec.begin();
        ans+=vec[q-1].second*(it->second);
    }
    cout<


你可能感兴趣的:(ACM,笔试)