欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Codeforces Beta Round #3 B. Lorry(贪心)

程序员文章站 2022-05-09 17:41:58
...

B. Lorry

time limit per test:2 seconds

memory limit per test:64 megabytes

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.

Input

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 ti, pi (1 ≤ ti ≤ 2; 1 ≤ pi ≤ 104), where ti is the vehicle type (1 – a kayak, 2 – a catamaran), and pi is its carrying capacity. The waterborne vehicles are enumerated in order of their appearance in the input file.

Output

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.

题意:一个旅游团打算坐皮舟和游艇旅游。他们租了一辆卡车把皮舟和游艇运到出发地。所有的皮舟的尺寸都是1m³,所有的的游艇都是2m³。每个皮舟或游艇都有其特定的运输能力,相同种类的交通工具也会有不同的运输能力。已知卡车的装载体积和每个皮舟或游艇的运输能力,找到一种装载组合使得卡车所运输的交通工具的运输能力之和最大。

思路:因为数据太大了,用背包不能做,但是卡车需要装载的只有两种而已,可以用贪心的思路。

1.把皮舟和游艇的运输能力分别记录下来,排序。

2.运输能力大的游艇优先,用尽量多的游艇装满卡车。

3.运输能力大的皮舟优先,用皮舟装满卡车剩余部分。(如果游艇不能装满卡车)

4.剩余的皮舟中,拿出最大的两个与卡车中游艇最大的运输能力比较,如果皮舟的运输能力大就代替游艇,如果不行再比较运输能力更小的游艇。

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
    int p;
    int num;
}kay[100010],cat[100010];
vector<node>vans;
int cmp(node a,node b)
{
    return a.p>b.p;
}
int main(void)
{
    int n,v,k1=0,k2=0,t,p,point1=0,point2=0,ans=0;
    scanf("%d%d",&n,&v);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&t,&p);
        if(t==1)
        {
            kay[k1].p=p;
            kay[k1++].num=i+1;
        }
        else if(t==2)
        {
            cat[k2].p=p;
            cat[k2++].num=i+1;
        }
    }
    sort(kay,kay+k1,cmp);
    sort(cat,cat+k2,cmp);
    for(int i=0;i<k2;i++)
    {
        if(v>=2)
        {
            vans.push_back(cat[i]);
            point1=i;
            v-=2;
        }
        else
            break;
    }
    if(v>0)
    {
        for(int i=0;i<k1;i++)
        {
            if(v>=1)
            {
                vans.push_back(kay[i]);
                v--;
                point2=i+1;
            }
            else
                break;
        }
    }
    while(point2<k1-1&&point1>=0)
    {
        if(vans[point1].p<kay[point2].p+kay[point2+1].p)
        {
            vans.erase(vans.begin()+point1);
            vans.push_back(kay[point2]);
            vans.push_back(kay[point2+1]);
            point1--;
            point2+=2;
        }
        else
        {
            point1--;
        }
    }
    for(int i=0;i<vans.size();i++)
        ans+=vans[i].p;
    printf("%d\n",ans);
    for(int i=0;i<vans.size();i++)
    {
        printf("%d",vans[i].num);
        if(i==vans.size()-1)
            printf("\n");
        else
            printf(" ");
    }
    return 0;
}