由于背包的容量N很大,所以直接枚举的方法肯定超时。
所以我们可以按照性价比来分类枚举。
当v1/s1较大时选择让第一类尽量多,反之也是。
枚举的过程中以s1和s2的最小公倍数容量为一个节点,因为如果某种的数量再增加的话,就可以用另一种来代替。所以枚举的次数最多是min(s1-1,N/s2)或min(s2-1,N/s1)次
AC 代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
int main ()
{
ll v;
ll s1,v1,s2,v2;
ll m;
cin >> m;
for(ll k=1; k<=m; k++)
{
cin >> v>>s1 >> v1 >> s2 >> v2;
ll V=0;
ll cnt1=v/s1;
ll cnt2=v/s2;
if(v1*s2<=v2*s1)
{
for(ll i=0; i<=min(s2-1,cnt1); i++)
{
V=max(V,i*v1+((v-i*s1)/s2)*v2);
}
}
else
{
for(ll i=0; i<=min(s1-1,cnt2); i++)
{
V=max(V,i*v2+((v-i*s2)/s1)*v1);
}
}
cout << "Case #"<<k << ": " <<V<<endl;
}
return 0;
}