題目描述
臨近開學了,大家都忙着收拾行李準備返校,但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,0<V<10000),分別表示做完這張試卷所需的時間以及做完後能得到的價值! 輸入以0 0結束。
輸出
對應每組測試數據輸出I_Love_C能獲得的最大價值。
保留小數點2位
樣例輸入
4 20
4 10
5 22
10 3
1 2
0 0
樣例輸出
37.00
提示
float的精度可能不夠。 你應該使用double類型。
解題思路:記得當初剛開始學習DP的時候做了這道題,用DP的思想一直錯,後來才發現這道題不是DP,而是貪心。因爲結果會有小數點出現的。看代碼和註釋就能懂了。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
double w[21],v[21],r[21];
int i,j,m,n;
while(scanf("%d%d",&m,&n)!=EOF&&(m||n))
{
for(i=0; i<m; ++i)
{
scanf("%lf%lf",&w[i],&v[i]);
r[i]=v[i]/w[i];
}
//冒泡排序,按價值時間比從大到小序
for(i=0;i<m-1;++i)
for(j=i+1;j<m;++j)
{
if(r[j]>r[i])
{
swap(r[j],r[i]);
swap(w[j],w[i]);
swap(v[j],v[i]);
}
}
int s=0;
double value=0;
//如果剩餘時間足夠,那麼總價值加上這張試卷的價值,並繼續另一張;
//如果剩餘時間不足,則總價值加上剩餘時間*此張試卷的價值時間比
for(i=0;i<m;++i)
{
if(s+w[i]<=n)
{
value+=v[i];
s+=w[i];
}
else
{
value+=(n-s)*r[i];
break; //注意不要漏寫
}
}
printf("%.2lf\n",value);
}
return 0;
}