题意:有一个容量为n的箱子,有两种珠宝,占的体积和价值分别是s1,v1,s2,v2,求能装下的最大的价值总量。
分析:刚开始以为是背包问题,但其实没那么简单;后来分情况讨论还是不行;后来又暴力枚举,当然是超时了。正确做法是有一部分是用背包的贪心,另一部分用枚举!现在就是看哪一部分用贪心。
看别人的题解是:L = LCM(s1,s2),可是知道大于L的部分就用价值比高的,所以n%L的部分枚举,其余部分贪心,不过这样可能得到的还不是最优解,所以n%L+L的部分枚举,这样就可以了,具体原因我还没想明白。继续思考!
注意:枚举的时候用max(s1,s2),不然会超时。
总之这道题非常好,思维很重要。
代码:
#include<iostream> #include<cmath> using namespace std; long long t,n,s1,s2,v1,v2,ans,mx,tmp,l; int gcd(long long a,long long b) { if(a<b) swap(a,b); if(a%b==0) return b; return gcd(b,a%b); } int main() { cin>>t; for(int i=1;i<=t;i++){ mx=-1; cin>>n>>s1>>v1>>s2>>v2; l=s1*s2/gcd(s1,s2); int p=n/l,q=n%l; if(p){ p--; q+=l; } if(s1*v2<s2*v1) ans=p*l/s1*v1; else ans=p*l/s2*v2; if(s1<s2){ swap(s1,s2); swap(v1,v2); } for(int j=0;j<=q/s1;j++){ tmp=v1*j+v2*((q-j*s1)/s2); if(mx<tmp) mx=tmp; } ans+=mx; cout<<"Case #"<<i<<": "<<ans<<endl; } }
原文地址:http://blog.csdn.net/ac_0_summer/article/details/46136859