思路:先对时间排序,每次判断当前剩余时间能否加入一个元素。再判断当前选择的元素中有哪些是不符合规则的,全部删去,并返还时间。我用了multiset写了一个简单的堆模拟。
struct node {
int w;
int ti;
int id;
bool operator<(const node b)const
{
if (this->ti == b.ti)return this->w > b.w;
return this->ti < b.ti;//时间小的
}
}a[N];
struct node2
{
int w;
int ti;
int id;
bool operator<(const node2 b)const
{
if (this->w == b.w)return this->ti > b.ti;
return this->w < b.w;//检索无效的元素
}
};
int main()
{
int n, time;
while (cin >> n >> time)
{
multiset<node> st;
f(i, 1, n) { scanf("%d%d", &a[i].w, &a[i].ti);a[i].id = i;st.insert(a[i]); }
node2 b;
multiset<node2> st2;
while (1)
{
auto it = st.begin();
if (time >= it->ti)
{
time -= it->ti;
b.id = it->id, b.ti = it->ti, b.w = it->w;
st.erase(it);
st2.insert(b);
}
else break;
while (st2.begin()->w < st2.size())//删除无效的
{
time += st2.begin()->ti;
st2.erase(st2.begin());
}
if (st.empty())break;
}
cout << st2.size() << endl << st2.size() << endl;
for (auto I : st2)cout << I.id << " ";puts("");
}
return 0;
}