D - Data Center Gym - 100513D

The startup “Booble” has shown explosive growth and now it needs a new data center with the capacity of m petabytes. Booble can buy servers, there are n servers available for purchase: they have equal price but different capacities. The i-th server can store a i petabytes of data. Also they have different energy consumption — some servers are low voltage and other servers are not.

Booble wants to buy the minimum number of servers with the total capacity of at least m petabytes. If there are many ways to do it Booble wants to choose a way to maximize the number of low voltage servers. Booble doesn’t care about exact total capacity, the only requirement is to make it at least m petabytes.

Input
The first line contains two integer numbers n and m (1 ≤ n ≤ 2·105, 1 ≤ m ≤ 2·1015) — the number of servers and the required total capacity.

The following n lines describe the servers, one server per line. The i-th line contains two integers a i, l i (1 ≤ a i ≤ 1010, 0 ≤ l i ≤ 1), where a i is the capacity, l i = 1 if server is low voltage and l i = 0 in the opposite case.

It is guaranteed that the sum of all a i is at least m.

Output
Print two integers r and w on the first line — the minimum number of servers needed to satisfy the capacity requirement and maximum number of low voltage servers that can be bought in an optimal r servers set.

Print on the second line r distinct integers between 1 and n — the indices of servers to buy. You may print the indices in any order. If there are many solutions, print any of them.

Examples
Input
4 10
3 1
7 0
5 1
4 1
Output
2 1
4 2
Input
3 13
6 1
6 1
6 1
Output
3 3
1 2 3
Note
In the first example any pair of servers which includes the server 2 is a correct output.

题意:
每个数有A值B值。要求选最少的一些数,使得A值和不小于m。同时要求选中的这些数B值和尽可能大。

思路:
如果B值任意,那么还真的有点难写了(感觉要背包,定义 d p [ x ] dp[x] 为A值和为x时的B值最大和,但是此处明显无法开下数组)

B值只有0和1,那就好办了。把B为0的和B为1的分开,排序以后,枚举要取多少个B值为1的数,剩下的取B值为0的。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <string>
#include <iostream>
using namespace std;

typedef long long ll;
const int maxn = 2e5 + 7;

ll a[maxn];
ll a0[maxn],a1[maxn],sum0[maxn],sum1[maxn];

int cmp(int x,int y) {
    return a[x] < a[y];
}

int main() {
    int n;
    ll m;
    scanf("%d%lld",&n,&m);
    int cnt0 = 0,cnt1 = 0;
    for(int i = 1;i <= n;i++) {
        int x;
        scanf("%lld%d",&a[i],&x);
        if(x == 0) {
            a0[++cnt0] = i;
        }
        else {
            a1[++cnt1] = i;
        }
    }
    sort(a0 + 1,a0 + 1 + cnt0,cmp);
    sort(a1 + 1,a1 + 1 + cnt1,cmp);
    for(int i = 1;i <= cnt0;i++) {
        sum0[i] = sum0[i - 1] + a[a0[i]];
    }
    for(int i = 1;i <= cnt1;i++) {
        sum1[i] = sum1[i - 1] + a[a1[i]];
    }
    sort(a + 1,a + 1 + n);
    ll num = 0;
    int R = 0,W = 0;
    for(int i = n;i >= 1;i--) {
        num += a[i];
        R++;
        if(num >= m) break;
    }
    for(int i = min(R,cnt1);i >= 0;i--) {
        ll num1 = sum1[cnt1] - sum1[cnt1 - i];
        ll num2 = sum0[cnt0] - sum0[cnt0 - (R - i)];
        if(num1 + num2 >= m) {
            W = i;break;
        }
    }
    
    printf("%d %d\n",R,W);
    for(int i = 1;i <= W;i++) {
        printf("%d ",a1[cnt1 - i + 1]);
    }
    for(int i = 1;i <= R - W;i++) {
        printf("%d ",a0[cnt0 - i + 1]);
    }
    return 0;
}
原创文章 930 获赞 38 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/106053953