CF3B 贪心

原创 2015年07月09日 21:34:15

http://codeforces.com/problemset/problem/3/B

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 ≤ 1051 ≤ v ≤ 109), 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 ≤ 21 ≤ 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.

Sample test(s)
input
3 2
1 2
2 7
1 3
output
7
2

/**
CF3B 贪心
题目大意;给定一个指定容量的背包,有n种物品,每种物品给定体积(1 or 2)和价值,问背包最多能容的价值是多少,并且求出装了哪几个物品
解题思路:背包问题,可惜背包容量过大。采用贪心的思想来做:按照价值/体积的递减顺序排序,从头依次装物品,直到装不下跳出循环。
          此时如果背包没有装满,那么肯定差1,有两种方案:1,从后面加价值最大的一个体积为1的物品。2,从前面取价值最小体积为1的物品去掉
          然后在后面加上价值最大的一个体积为2的物品,二者取最优
*/
#include <string.h>
#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;
struct note
{
    int x,y;
    int id,judge;
    bool operator < (const note & other)const
    {
        return x*other.y<other.x*y;
    }
} a[1000505];
int n,m,b[1050005];
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0; i<n; i++)
        {
            scanf("%d%d",&a[i].x,&a[i].y);
            a[i].id=i+1;
            a[i].judge=0;
        }
        sort(a,a+n);
        int sum=0,flag=-1;
        for(int i=0; i<n; i++)
        {
            if(m-a[i].x>=0)
            {
                sum+=a[i].y;
                a[i].judge=1;
                m-=a[i].x;
                flag=i;
            }
            else
            {
                break;
            }
        }
        if(m>0&&flag<n)
        {
            int sum1=-1,sum2=-1,flag1,flag2=-1,flag3;
            ///后加1
            for(int i=flag+1; i<n; i++)
            {
                if(a[i].x==1)
                {
                    sum1=sum+a[i].y;
                    flag1=i;
                    break;
                }
            }
            ///前去1后加2
            for(int i=flag; i>=0; i--)
            {
                if(a[i].x==1)
                {
                    sum2=sum-a[i].y;
                    flag2=i;
                    for(int j=flag+1; j<n; j++)
                    {
                        if(a[j].x==2)
                        {
                            sum2+=a[j].y;
                            flag3=j;
                            break;
                        }
                    }
                    break;
                }
            }
            if(sum1>=sum2&&sum1>sum)
            {
                sum=sum1;
                a[flag1].judge=1;
            }
            else if(sum2>=sum1&&sum2>sum)
            {
                sum=sum2;
                a[flag2].judge=0;
                a[flag3].judge=1;
            }
        }
        printf("%d\n",sum);
        int num=0;
        for(int i=0; i<n; i++)
        {
            if(a[i].judge==1)
            {
                b[num++]=a[i].id;
            }
        }
        for(int i=0; i<num; i++)
        {
            printf(i==num-1?"%d\n":"%d ",b[i]);
        }
    }
    return 0;
}
/**
3 2
1 2
2 7
1 3

3 2
1 2
1 3
1 4

3 3
2 8
2 7
1 3

3 3
2 8
2 7
2 3

3 3
1 4
1 3
2 5
*/


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

CF - 805B. 3-palindrome - 贪心+构造

1.题目描述: B. 3-palindrome time limit per test 1 second memory limit per test 256 mega...

CF Round #616 (A,B,C 字符串,贪心,DFS)

http://codeforces.com/problemset/problem/616/AA题:比较两个长整数的大小(可能含有前导0), 数据位数高达10^6位;考虑用字符串 一开始想的是把前导0...

CF - 797B. Odd sum - 贪心

题目描述: B. Odd sum time limit per test 1 second memory limit per test 256 meg...

CF - 757B. Bash's Big Day - 贪心+暴力

1.题目描述: B. Bash's Big Day time limit per test 2 seconds memory limit per test 512 m...

CF - 801B. Valued Keys - 构造+贪心

1.题目描述: B. Valued Keys time limit per test 2 seconds memory limit per test 256 megabytes inp...

CF578B 贪心+预处理优化+思维到位

题目描述: D. "Or" Game time limit per test 2 seconds memory limit per test 256 megabytes input s...

cf 540b School Marks 贪心

题意:一共要写n个数,已经写了k个数,要求写出接下来的n-k个数。要求每个数小于等于p,大于等于1。所有数总和小于等于x。中位数必须是大于等于y。 做法:贪心,因为有上限要求,又要改变中位数,所以只...

CF - 596B. Wilbur and Array 贪心

1.题目描述: B. Wilbur and Array time limit per test 2 seconds memory limit per test 256 megabytes ...

CF - 555B. Case of Fugitive 排序+贪心

1.题目描述: B. Case of Fugitive time limit per test 3 seconds memory limit per test 256...

CF #347 (Div.2) B. Rebus(贪心)

题目链接: CF #347 (Div.2) B. Rebus 题意: 给一串只含加号和减号的运算式,以及运算结果为n,运算数全是’?’,问能否用不大于n的正整数代替所有的’?’,使得等式成立?如...
  • Ramay7
  • Ramay7
  • 2016年04月17日 09:21
  • 265
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CF3B 贪心
举报原因:
原因补充:

(最多只允许输入30个字)