题意:
给定一个容积为n的箱子,装两种宝物,每一种宝物有数量s和价值v这两个参数,问如何装才能使价值最大(输入均为32位带符号的整数)
思路
一开始肯定会想到贪心来找性价比高的,但是举个例子(n=100,s1=90,v1=90;s2=25,s2=24)此时物体1的性价比高,但是放了物体1才价值90,如果全部放物体2有价值96,所以不仅仅只看性价比,这个时候我们应该来枚举性价比低的那个物体(物体2),但是范围是多少??这个时候你是不是想到了一个范围(<=n/s2),没错,但是当n比较大s2比较小的时候你会发现(n/s2)数据就比较大了,枚举可能会超时,那我们还需要一个范围,仔细想想,物体1性价比高等价于(v1s2>=v2s1),此时我们枚举的又是物体2,聪明的你肯定发现,v2*s1中s1可以看成物体2的数量,这此时物体2的数量肯定不会超过s1,因为如果>=s2,那我们可以用性价比更好的物体1来代替,所以就又得到一个范围(<=s1-1);;当物体2性价比高的时候情况和上面类似。。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ll t,i,n,ans=0,s1,s2,v1,v2,k=1;
cin>>t;
while(t--){
ans=0;
cin>>n>>s1>>v1>>s2>>v2;
if(v1*s2>=v2*s1){
//1性价比高,枚举2
for(i=0;i<=min(n/s2,s1-1);i++){
ans=max(ans,i*v2+((n-i*s2)/s1)*v1);//总价值=(物体2价值+物体1价值)= i*v2+((n-i*s2)/s1)*v1)
}
}
else {
//2性价比高,枚举1
for(i=0;i<=min(n/s1,s2-1);i++){
ans=max(ans,i*v1+((n-i*s1)/s2)*v2);
}
}
printf("Case #%lld: %lld\n",k++,ans);
}
return 0;
}