天天看點

問題 E: Homework[貪心]

題目描述

臨近開學了,大家都忙着收拾行李準  備返校,但 I_Love_C 卻不為此擔心! 因為他的心思全在暑假作業上:目前為止還未開動。

暑假作業是很多張試卷,我們這些從試卷裡爬出來的人都知道,卷子上的題目有選擇題、填空題、簡答題、證明題等。而做選擇題的好處就在于工作量很少,但又因為選擇題題目都普遍很長。如果有 5 張試卷,其中 4 張是選擇題,最後一張是填空題,很明顯做最後一張所花的時間要比前 4 張長很多。但如果你隻做了選擇題,雖然工作量很少,但表面上看起來也已經做了4/5的作業了。

I_Love_C決定就用這樣的方法來蒙混過關,他統計出了做完每一張試卷所需的時間以及它做完後能得到的價值(按上面的原理,選擇題越多價值當然就越高咯)。

現在就請你幫他安排一下,用他僅剩的一點時間來做最有價值的作業。

輸入

測試資料包括多組。每組測試資料以兩個整數 M,N(1<M<20,1<N<10000) 開頭,分别表示試卷的數目和 I_Love_C 剩下的時間。接下來有 M 行,每行包括兩個整數 T,V(1<T<N,1<V<10000)分别表示做完這張試卷所需的時間以及做完後能得到的價值,輸入以 0 0 結束。

輸出

對應每組測試資料輸出 I_Love_C 能獲得的最大價值。保留小數點 2 位

提示:float 的精度可能不夠,你應該使用 double 類型。

樣例輸入

<span style="color:#333333">4 20
4 10
5 22
10 3
1 2
0 0
</span>
           

樣例輸出

<span style="color:#333333">37.00
</span>
           

提示

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f;
priority_queue<int,vector<int>,greater<int>>q;
 
struct stu
{
    double time;
    double value;
    double v_t;
};
 
bool cmp(stu a,stu b)
{
    return a.v_t>b.v_t;
}
 
int main()
{
    int m,n;
    while(cin>>m>>n&&(m!=0&&n!=0))
    {
        stu s[50];
        for(int i=0;i<m;i++)
        {
            cin>>s[i].time>>s[i].value;
            s[i].v_t=s[i].value/s[i].time;
        }
        double t=0,v=0;
        sort(s,s+m,cmp);
        for(int i=0;i<m;i++)
        {
            if(t+s[i].time<=n)
            {
                t+=s[i].time;
                v+=s[i].value;
            }
            else
            {
                if(t<n)
                {
                    v+=(n-t)*s[i].v_t;
                    break;
                }
            }
        }
        printf("%.2f\n",v);
    }
    return 0;
}
 
           

bool

cmp(stu a,stu b)

{

return

a.v_t>b.v_t;

}

貪心排序要按value/time的值從小到大排,重載>

v+=(n-t)*s[i].v_t;

感覺這道題很有病的一點是還要加做了一半的

有參考