临近开学了,大家都忙着收拾行李准备返校,但I_Love_C却不为此担心! 因为他的心思全在暑假作业上:目前为止还未开动(-_-!!还以为他有多冷静呢)。 暑假作业是很多张试卷,我们这些从试卷里爬出来的人都知道,卷子上的题目有选择题、填空题、简答题、证明题等。 而做选择题的好处就在于工作量很少,但又因为选择题题目都普遍很长。 如果有5张试卷,其中4张是选择题,最后一张是填空题,很明显做最后一张所花的时间要比前4张长很多。 但如果你只做了选择题,虽然工作量很少,但表面上看起来也已经做了4/5的作业了。 I_Love_C决定就用这样的方法来蒙混过关。 他统计出了做完每一张试卷所需的时间以及它做完后能得到的价值(按上面的原理,选择题越多价值当然就越高咯)。 现在就请你帮他安排一下,用他仅剩的一点时间来做最有价值的作业。
Input
测试数据包括多组。 每组测试数据以两个整数M,N(1≤M≤20, 1≤N≤10000)开头,分别表示试卷的数目和I_Love_C剩下的时间。 接下来有M行,每行包括两个整数T,V(1≤T≤N,0
Output
对应每组测试数据输出I_Love_C能获得的最大价值。保留小数点2位。
Sample Input
4 20
4 10
5 22
10 3
1 2
0 0
Sample Output
37.00
4 个解决方案
#1
input 写的不是很详细,而且题目里的计算要求也有点不清楚啊!
#2
说简单一点,这就是0-1背包问题,也可以说是动态规划等等
#3
写一个用STL做的代码,这种动态问题一般没有最优解,只有近似解:
#include<iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <iomanip>
using namespace std;
double partnumber(int n)
{
double dResult = 0.0;
dResult = exp((double)-1)*n;
return dResult;
}
class TestData
{
public:
TestData(int t,int v):m_nTime(t),m_nValue(v)
{
m_dValue = (double)(m_nValue)/(double)(m_nTime);
}
bool operator >(const TestData& td) const
{
return m_dValue > td.m_dValue;
}
int GetTime()
{
return m_nTime;
}
int GetValue()
{
return m_nValue;
}
double GetValuePerTime()
{
return m_dValue;
}
~TestData(){}
private:
int m_nTime;
int m_nValue;
double m_dValue;
};
int main()
{
int M,N,T,V,nTime = 0;
double nRsult = 0;
vector<TestData> vec;
cout << "Input the Number M & N: " << endl;
cin >> M >> N;
for (int i = 0; i < M; ++i)
{
cout << "Please input the " << (i+1) << " group data:" << endl;
cin >> T >> V;
while(T > N)
{
cout << "Bad input,Please input the " << (i+1) << " group data again:" << endl;
cin >> T >> V;
}
TestData td(T,V);
vec.push_back(td);
}
sort(vec.begin(),vec.end(),greater<TestData>());
vector<TestData>::iterator pos;
for(pos = vec.begin();pos != vec.end(); ++pos)
{
nTime += pos->GetTime();
if (nTime > N)
{
nRsult += pos->GetValuePerTime()*(N - (nTime - pos->GetTime()));//如果需要的是完整的试卷,这部分需要注释掉,这样很可能达不到最优解
break;
}else
{
nRsult += pos->GetValue();
}
}
cout << "The best value is: " << nRsult << endl;
return 0;
}
#4
谢谢。。知道了。
#1
input 写的不是很详细,而且题目里的计算要求也有点不清楚啊!
#2
说简单一点,这就是0-1背包问题,也可以说是动态规划等等
#3
写一个用STL做的代码,这种动态问题一般没有最优解,只有近似解:
#include<iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <iomanip>
using namespace std;
double partnumber(int n)
{
double dResult = 0.0;
dResult = exp((double)-1)*n;
return dResult;
}
class TestData
{
public:
TestData(int t,int v):m_nTime(t),m_nValue(v)
{
m_dValue = (double)(m_nValue)/(double)(m_nTime);
}
bool operator >(const TestData& td) const
{
return m_dValue > td.m_dValue;
}
int GetTime()
{
return m_nTime;
}
int GetValue()
{
return m_nValue;
}
double GetValuePerTime()
{
return m_dValue;
}
~TestData(){}
private:
int m_nTime;
int m_nValue;
double m_dValue;
};
int main()
{
int M,N,T,V,nTime = 0;
double nRsult = 0;
vector<TestData> vec;
cout << "Input the Number M & N: " << endl;
cin >> M >> N;
for (int i = 0; i < M; ++i)
{
cout << "Please input the " << (i+1) << " group data:" << endl;
cin >> T >> V;
while(T > N)
{
cout << "Bad input,Please input the " << (i+1) << " group data again:" << endl;
cin >> T >> V;
}
TestData td(T,V);
vec.push_back(td);
}
sort(vec.begin(),vec.end(),greater<TestData>());
vector<TestData>::iterator pos;
for(pos = vec.begin();pos != vec.end(); ++pos)
{
nTime += pos->GetTime();
if (nTime > N)
{
nRsult += pos->GetValuePerTime()*(N - (nTime - pos->GetTime()));//如果需要的是完整的试卷,这部分需要注释掉,这样很可能达不到最优解
break;
}else
{
nRsult += pos->GetValue();
}
}
cout << "The best value is: " << nRsult << endl;
return 0;
}
#4
谢谢。。知道了。