贪心背包——Lorry

Lorry

题面翻译

题目描述

给定整数 n , v n,v n,v

有一辆载重量为 v v v 的货车,准备运送两种物品。物品 A 的重量为 1 1 1,物体 B 的重量为 2 2 2,每个物品都有一个价值 p i p_i pi。求货车可以运送的物品的最大价值。

输入格式

第一个行包含两个整数 n n n v v v,分别表示有 n n n 个物品,货车的载重量为 v v v。( 1 ≤ n ≤ 1 0 5 1\le n\le10^5 1n105 1 ≤ v ≤ 1 0 9 1\le v\le10^9 1v109

接下来 n n n 行,每行两个整数,分别表示物品的重量 t i t_i ti 和价值 p i p_i pi。( t i = 1 t_i=1 ti=1 2 2 2 1 ≤ p i ≤ 1 0 4 1\le p_i\le10^4 1pi104

输出格式

第一行,一个整数,表示价值之和的最大值。

第二行,构成最大价值的物品的编号(如果答案不唯一,请输出其中任何一个)。

题目描述

A group of tourists is going to kayak and catamaran tour. A rented lorry has arrived to the boat depot to take kayaks and catamarans to the point of departure. It’s known that all kayaks are of the same size (and each of them occupies the space of 1 cubic metre), and all catamarans are of the same size, but two times bigger than kayaks (and occupy the space of 2 cubic metres).

Each waterborne vehicle has a particular carrying capacity, and it should be noted that waterborne vehicles that look the same can have different carrying capacities. Knowing the truck body volume and the list of waterborne vehicles in the boat depot (for each one its type and carrying capacity are known), find out such set of vehicles that can be taken in the lorry, and that has the maximum total carrying capacity. The truck body volume of the lorry can be used effectively, that is to say you can always put into the lorry a waterborne vehicle that occupies the space not exceeding the free space left in the truck body.

输入格式

The first line contains a pair of integer numbers $ n $ and $ v $ ( $ 1<=n<=10^{5} $ ; $ 1<=v<=10^{9} $ ), where $ n $ is the number of waterborne vehicles in the boat depot, and $ v $ is the truck body volume of the lorry in cubic metres. The following $ n $ lines contain the information about the waterborne vehicles, that is a pair of numbers $ t_{i} $ , $ p_{i} $ ( $ 1<=t_{i}<=2 $ ; $ 1<=p_{i}<=10^{4} $ ), where $ t_{i} $ is the vehicle type ( $ 1 $ – a kayak, $ 2 $ – a catamaran), and $ p_{i} $ is its carrying capacity. The waterborne vehicles are enumerated in order of their appearance in the input file.

输出格式

In the first line print the maximum possible carrying capacity of the set. In the second line print a string consisting of the numbers of the vehicles that make the optimal set. If the answer is not unique, print any of them.

样例 #1

样例输入 #1

3 2
1 2
2 7
1 3

样例输出 #1

7
2

思路

这道题看起来很像是01背包问题,但细看数据范围, V < = 1 0 9 V<=10^9 V<=109,那么如果用背包会炸,我们又观察题目,只有两种物品,因此我们可以考虑贪心(我觉得,背包问题如果不能用,但题目又的确是背包问题的思路,我们就直接用贪心)。

  • 贪心的思路:我们可以通过枚举体积(因为本道题体积就只有1和2),我们可以先用pair来存储编号和价值(为什么要编号,因为题目最后要叫我们求出最大值所对应的编号),接着我们对A和B进行从大到小进行排序,然后对A物品取出的体积进行遍历,这里要注意的是:枚举用了i个A,剩下的B就是有(V-i)/2个,然后去最小值(个数尽可能的少最好,因为体积),然后就更新价值(这里可以优化一下,把B的价值前缀和先算出来)。代码中有maxvi,maxvj,这个是干什么的呢?当然是用来记录更新最大值的时候A和B的编号。(因为已经排序过了,因此你用这个来是为了在排序过后的前i个可以构成最大价值的物品的编号)

代码

//第一问为01背包问题,但本道题V太大了,不能用,因此只能用贪心做
//第二问求类似方案数

#include<iostream>
#include<algorithm>
#define int long long
#define x first
#define y second

using namespace std;

const int N = 1e5+10;

typedef pair<int,int>PII;

PII a[N],b[N];//放入价值和编号
int s[N];
int n,V;
int c1,c2,ans;

bool cmp(PII a,PII b){
    return a.x>b.x;
}

signed main(){
    cin>>n>>V;
    
    for(int i=1;i<=n;i++){
        int a1,b1;
        cin>>a1>>b1;
        if(a1==1){
            a[++c1]={b1,i};//A物品
        }else{
            b[++c2]={b1,i};//B物品
        }
    }
    
    sort(a+1,a+c1+1,cmp);
    sort(b+1,b+c2+1,cmp);
    
    for(int i=1;i<=c2;i++){
        s[i]=s[i-1]+b[i].x;
    }
    
    int maxvi=0,maxvj=0;
    int sum=0;
    for(int i=0;i<=c1&&i<=V;i++){//枚举用了i个A,剩下的B就是(V-i)/2
        int j=min((V-i)>>1,c2);
        sum+=a[i].x;
        if(sum+s[j]>ans){
            ans=sum+s[j];
            maxvi=i;
            maxvj=j;
        }
    }
    
    cout<<ans<<endl;
    
    for(int i=1;i<=maxvi;i++){
        cout<<a[i].y<<' ';
    }
    for(int j=1;j<=maxvj;j++){
        cout<<b[j].y<<" ";
    }
    
    return 0;
}
  • 28
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

green qwq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值