Description
You are preparing for an exam on scheduling theory. The exam will last for exactly T milliseconds and will consist of n problems. You can either solve problem i in exactly ti milliseconds or ignore it and spend no time. You don’t need time to rest after solving a problem, either.
Unfortunately, your teacher considers some of the problems too easy for you. Thus, he assigned an integer ai to every problem i meaning that the problem i can bring you a point to the final score only in case you have solved no more than ai problems overall (including problem i).
Formally, suppose you solve problems p1, p2, …, pk during the exam. Then, your final score s will be equal to the number of values of j between 1 and k such that k ≤ apj.
You have guessed that the real first problem of the exam is already in front of you. Therefore, you want to choose a set of problems to solve during the exam maximizing your final score in advance. Don’t forget that the exam is limited in time, and you must have enough time to solve all chosen problems. If there exist different sets of problems leading to the maximum final score, any of them will do.
Input
The first line contains two integers n and T (1 ≤ n ≤ 2·10 5 ; 1 ≤ T ≤ 10 9 ) — the number of problems in the exam and the length of the exam in milliseconds, respectively.
Each of the next n lines contains two integers a i and t i (1 ≤ a i ≤ n; 1 ≤ t i ≤ 10 4 ). The problems are numbered from 1 to n.
Output
In the first line, output a single integer s — your maximum possible final score.
In the second line, output a single integer k (0 ≤ k ≤ n) — the number of problems you should solve.
In the third line, output k distinct integers p 1 , p 2 , …, p k (1 ≤ p i ≤ n) — the indexes of problems you should solve, in any order.
If there are several optimal sets of problems, you may output any of them.
Examples
Input |
---|
5 300 3 100 4 150 4 80 2 90 2 300 |
Output |
2 3 3 1 4 |
Input |
---|
2 100 1 787 2 788 |
Output |
0 0 |
Input |
---|
2 100 2 42 2 58 |
Output |
2 2 1 2 |
Note
In the first example, you should solve problems 3, 1, and 4. In this case you’ll spend 80 + 100 + 90 = 270 milliseconds, falling within the length of the exam, 300 milliseconds (and even leaving yourself 30 milliseconds to have a rest). Problems 3 and 1 will bring you a point each, while problem 4 won’t. You’ll score two points.
In the second example, the length of the exam is catastrophically not enough to solve even a single problem.
In the third example, you have just enough time to solve both problems in 42 + 58 = 100 milliseconds and hand your solutions to the teacher with a smile.
tourist的题解在这里http://codeforces.com/blog/entry/56992
题意:n个任务有两个指标
ai
:完成的任务总数超过
ai
时该任务不计分,
ti
:完成该任务需要的时间,求给定时间T内,最多得几分。
分析:从0到n逐渐增加题目数的方向来分析似乎很困难,不如分析一下问题的解的情况:如果得分为K,那么一定要做K道
ai
>=K的题目,而
ai
< K的题目做了也不会得分而且会浪费时间,所以最好的答案就是不少于K个
ai
≥ K的题目,并且
∑ti
≤T,为了让
ti
的和最小,应选取能得分的题目中
ti
最小的K个来做。
思路:二分查找K,以K生成一个最优的答案,如果最优的答案是存在的,那么K是可行的,可以往更大的方向寻找,如果不行,就往更小的方向寻找。在本题中,显然当K满足时,K-1也满足(少做一道题就行了),所以二分是可以的。
PS:研究了tourist的代码学会了很多东西,比如vector的初始化和resize可以节约时间,以前觉得vector会很慢,其实当算法优化到O(n × log(n))时候,vector带来的系数完全是可以接受的,只要在要用到它的地方考虑好大小利用初始化和resize节约时间,vector就能节省很多代码量
#include<stdio.h>
#include<algorithm>
using std::sort;
#include <vector>
using std::vector;
using std::pair;
//#define N_max 200005
int n,T;
typedef vector<int> vect;
typedef vector<pair<int, int>> vecp;
int main() {
scanf("%d %d", &n,&T);
vect c(n), t(n),res;
for (int i = 0; i < n; ++i) {
scanf("%d %d", &c[i], &t[i]);
}
int l = 0, r = n+1, mid = (l + r) / 2;
int sum,flag;
vecp a;
while (l+1<r)
{
mid = (l + r) / 2;
//check mid
sum = 0; flag = 0;
a.clear();
for (int i = 0; i < n; ++i) {
if (c[i] >= mid) {
a.emplace_back(t[i],i);
}
}
if (a.size() >= mid) {
sort(a.begin(), a.end());
//choose the first ti
sum = 0;
for (int t = 0; t < mid; ++t) {
sum += a[t].first;
}
if (sum <= T) {
flag = 1;
}
else {
flag = 0;
}
}
else {
flag = 0;
}
//mid is ok
if(flag){
l = mid;
res.resize(l);
for (int p = 0; p < l; ++p) {
res[p] = a[p].second;
}
}
else {
r = mid;
}
}
printf("%d\n", l);
printf("%d\n", res.size());
for (int t = 0; t < res.size(); ++t) {
printf("%d%c", res[t]+1, t == res.size() - 1 ? '\n' : ' ');
}
}