一中OJ | #3514 礼物
时限 1000MS/Case 内存 128MB/Case
题目描述
你有一个体积为N的箱子和两种数量无限的宝物。宝物1的体积为S1,价值为V1,宝物2的体积为S2,价值为V2。你的任务是计算箱子最多能装多大价值的宝物。注意每种宝物都必须拿非负整数个。
输入格式
多组数据,每组数据占一行,包含五个整数:N,S1,V1,S2,V2,他们的意义如题目描述。
输出格式
每组数据输出一行,表示箱子能装入的宝物的最大价值。
样例输入
100 1 1 2 2
100 34 34 5 3
样例输出
100
86
数据范围
N,S1,V1,S2,V2均为32位带符号整数。
最多不超过100组数据。
----------------------------------------------------------
题目分析
枚举题,需要将时间复杂度降到o(sqrt(n))比较好过
所以将每组数据划分四种情况
1.当S1 == S2
这种很简单就不用说了
2.当S1 >= sqrt(n) 且 S1 >= S2
枚举S1的个数,算最大的ans
3.当S2 >= sqrt(n) 且 S2 >= S1
同(2.),枚举S2的个数,算最大的ans
4.当S1 < sqrt(n) 且 S2 < sqrt(n)
以S1*S2为一个单位,假设选择S2个物品1,S1个物品2,那么总体积都是S1*S2,选择物品1的价值就是S2*V1,物品2是S1*V2。这样就可以最优化选择一种物品。剩下的部分重复(2.)(3.)步骤即可
----------------------------------------------------------
代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#define hashsize 1000003
#define inf 0x7f7f7f7f
using namespace std;
int main()
{
// freopen("Outp.txt","w+",stdout);
long long n,s1,s2,v1,v2;
while(cin>>n>>s1>>v1>>s2>>v2)
{
if(s1==s2)
{
cout<<(long long)(n/s1)*max(v1,v2)<<endl;
continue;
}
long long c1=0,c2=0,ans=0,subb=0;
if(s1>s2 && s1*s1>=n) //当s1比较大
{
for(c1=0;c1*s1<=n;c1++)
{
ans=max(ans,(long long)c1*v1+(n-c1*s1)/s2*v2);
}
}
else if(s2>s1 && s2*s2>=n) //当s2比较大
{
for(c2=0;c2*s2<=n;c2++)
{
ans=max(ans,(long long)c2*v2+(n-c2*s2)/s1*v1);
}
}
else
{
if(s1*v2>s2*v1) //取物品2更划算
{
ans=(n/(s1*s2))*s1*v2; //先取尽量多的物品2
n=n%(s1*s2);
if(s1>s2 && s1*s1>=n) //当s1比较大
{
for(c1=0;c1*s1<=n;c1++)
{
subb=max(subb,c1*v1+(n-c1*s1)/s2*v2);
}
}
else if(s2>s1 && s2*s2>=n) //当s2比较大
{
for(c2=0;c2*s2<=n;c2++)
{
subb=max(subb,c2*v2+(n-c2*s2)/s1*v1);
}
}
ans+=subb;
}
else //取物品1更划算
{
ans=(n/(s1*s2))*s2*v1;
n=n%(s1*s2);
if(s1>s2 && s1*s1>=n) //当s1比较大
{
for(c1=0;c1*s1<=n;c1++)
{
subb=max(subb,c1*v1+(n-c1*s1)/s2*v2);
}
}
else if(s2>s1 && s2*s2>=n) //当s2比较大
{
for(c2=0;c2*s2<=n;c2++)
{
subb=max(subb,c2*v2+(n-c2*s2)/s1*v1);
}
}
ans+=subb;
}
}
cout<<ans<<endl;
}
return 0;
}