You Like Cake(超大01背包模板题)

You Like Cake

题目描述

双十一就要来啦!而Yuno刚刚获得了一笔X元的奖金。那么是不是应该清空下购物车呢?
购物车总共有N个物品,每个物品的价格为Vi,Yuno想尽可能地把手头的奖金给花光,所以她要精心挑选一些商品,使得其价格总和最接近但又不会超过奖金的金额。那么Yuno最后最少可以剩下多少钱呢?

输入

第一行,两个正整数N和X。
第二行,N个正整数Vi表示第i个物品的价格。

输出

输出一个整数,表示Yuno最后最少可以剩下的钱数。

样例输入

4 50
1 2 3 4

样例输出

40

提示

对于100的数据,N≤40,X,Vi≤109

背包容量过大采用折半之后二进制枚举子集,再二分查找

upper_bound返回的是第一个大于查找的数的位置

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[25],b[25];
ll s[(1<<21)+1],f[(1<<21)+1];
int main(){
    int n;
    ll m;scanf("%d%lld",&n,&m);
    for(int i=1;i<=n;++i){
        if(i<=n/2){
            scanf("%lld",&a[i]);
        }
        else scanf("%lld",&b[i-n/2]);
    }
    int k=n/2;
    int pos=0;
    for(int i=0;i<(1<<k);++i){
        for(int j=1;j<=k;++j){
            if(i&(1<<(j-1))){
                s[pos]+=a[j];
            }
        }
        pos++;
    }
    int len=(int)(unique(s,s+pos)-s);
    sort(s,s+len);
    pos=0;k=n-k;
    for(int i=0;i<(1<<k);++i){
        for(int j=1;j<=k;++j){
            if(i&(1<<(j-1))){
                f[pos]+=b[j];
            }
        }
        pos++;
    }
    ll ans=0;
    int op;
    for(int i=0;i<pos;++i){
            if(m<f[i]) continue;
            op=upper_bound(s,s+len,m-f[i])-s;
            op--;
            if(op>=0){
               ans=max(ans,s[op]+f[i]);
            }
    }
    printf("%lld\n",m-ans);
    return 0;
}

原文地址:https://www.cnblogs.com/smallocean/p/10284664.html

时间: 2024-12-13 06:22:31

You Like Cake(超大01背包模板题)的相关文章

1085 背包问题(0-1背包模板题)

1085 背包问题(0-1背包模板题)(51NOD基础题) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 在N件物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2--Wn(Wi为整数),与之相对应的价值为P1,P2--Pn(Pi为整数).求背包能够容纳的最大价值. Input 第1行,2个整数,N和W中间用空格隔开.N为物品的数量,W为背包的容量.(1 <= N <= 100,1 <= W <= 10000) 第2 - N + 1行,每行

POJ 3624 Charm Bracelet(01背包裸题)

Charm Bracelet Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 38909   Accepted: 16862 Description Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like to fill it with the best charms possible fro

D. Arpa&#39;s weak amphitheater and Mehrdad&#39;s valuable Hoses 分组背包模板题

http://codeforces.com/problemset/problem/742/D 并查集预处理出所有关系. 一开始的时候,我预处理所有关系后,然后选择全部的时候,另起了一个for,然后再判断. 这样是不对的.因为这样使得同一组里面可能选择了两次. 3 0 2 1 2 3 1 1 3 #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include &

01背包水题篇之 HDU2955——Robberies

原来是想dp[i],表示不被抓概率为i所能抢到的最大钱(概率1-100) 后来看了别人的博客是dp[i]表示抢了i钱最大的不被抓概率,嗯~,弱菜水题都刷不动. 那么状态转移方程就是 dp[i]=max(dp[i],dp[i-money]*p),初始化dp(0~maxn)为0,dp[0]=1(1毛钱都没抢你抓个毛线啊,哥是良民~) 又是贴代码环节~ <span style="font-size:18px;">#include<iostream> #include&

01背包 模板1 2 总结

物品质量 w[0] w[1]  w[2] ....... w[n]                背包容量c               T 物品价值 v[0]  v[1]  v[2]  .......  v[n]              物品种类 n                N (一)设DP(x,y)   表示  从前x项物品中  取出装入  体积为y的背包 的  物品的最大价值. 前x项物品(0---- x-1 , X)   去装          体积容量为y的背包 |------

01背包水题篇之HDU3466——Proud Merchants

这是个好题,菜鸟刚学dp,这题把我以前的想法全都给完完全全的颠覆了.其实是自己没了解无后效性的概念. 然后我去开开心心滴跑去问队长:"队长,队长,怎么理解动归的无后效性啊???" 学长很深沉滴对我说:"做多了就会了" "噢噢"(好吧) 然后学长又补了句:"能构成有向无环图的都能用DP搞." 我心里想:"队长就知道搞妹~~~." 默默去翻小白书看看DAG去了. 为了搞清楚这题怎么写,操了度娘千百遍,还是没搞定

01背包模板、全然背包 and 多重背包(模板)

转载请注明出处:http://blog.csdn.net/u012860063 贴一个自觉得解说不错的链接:http://www.cppblog.com/tanky-woo/archive/2010/07/31/121803.html 模版就直接贴代码: 01背包模板: /* 01背包问题 01背包问题的特点是,">每种物品仅有一件.能够选择放或不放. 01背包问题描写叙述: 有N件物品和一个容量为V的背包. 第i件物品的重量是c[i],价值是w[i]. 求解将哪些物品装入背包可使这些物品

HDU 2602 Bone Collector(01背包裸题)

Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 60469    Accepted Submission(s): 25209 Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bo

hihocoder第七周 完全背包模板题

时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说之前的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的时刻了! 等等,这段故事为何似曾相识?这就要从平行宇宙理论说起了………总而言之,在另一个宇宙中,小Ho面临的问题发生了细微的变化! 小Ho现在手上有M张奖券,而奖品区有N种奖品,分别标号为1到N,其中第i种奖品需要need(i)张奖券进行兑换,并且可以兑换无数次,为了使得辛苦得到的奖券不白白浪费,小Ho给每件奖品都评了分,其