1. 程式人生 > >D. Too Easy Problems(二分,排序,貪心)

D. Too Easy Problems(二分,排序,貪心)

題目大意:給出n個問題和總時間t。

給出的n個問題,對於每個問題都有一個限制題數,如果答題數超過了該題的限制題數,該題不得分;以及每道題所需要花費的時間。

現在要求再規定時間內儘可能的拿高分。輸出結果不唯一,即順序不唯一,以及規定時間內做的不得分的題可算可不算。

思路:二分,排序,貪心等思路

對於答題的數量我們可以用二分的方法檢驗,判斷答題數量是否滿足。

其次在每個二分過程中,提取所有滿足的題目,並對這些題目按照時間的長短有小到大排序,最後檢驗一下提取出來的題目數量以及總的時間是否符合即可。

複雜度O(nlogn)

#include <bits/stdc++.h>
#include<vector>
using namespace std;

int main()
{
    int n, T;
    scanf("%d %d", &n, &T);
    vector<int> a(n), t(n);
    for (int i = 0; i < n; i++)
    {
        scanf("%d %d", &a[i], &t[i]);
    }
    vector<int> res;
    int low = 0, high = n;
    while (low < high)
    {
        int mid = (low + high + 1) >> 1;
        vector< pair<int,int> > e;
        for (int i = 0; i < n; i++)
        {
            if (a[i] >= mid)
            {
                e.push_back(make_pair(t[i], i));
            }
        }
        sort(e.begin(), e.end());
        bool ok = false;
        if ((int) e.size() >= mid)
        {
            int sum = 0;
            for (int i = 0; i < mid; i++)
            {
                sum += e[i].first;
            }
            if (sum <= T)
            {
                ok = true;
                res.resize(mid);
                for (int i = 0; i < mid; i++)
                {
                    res[i] = e[i].second;
                }
            }
        }
        if (ok)
        {
            low = mid;
        }
        else
        {
            high = mid - 1;
        }
    }
    int sz = (int) res.size();
    printf("%d\n%d\n", sz, sz);
    for (int i = 0; i < sz; i++)
    {
        if (i > 0)
        {
            putchar(' ');
        }
        printf("%d", res[i] + 1);
    }
    printf("\n");
    return 0;
}