题意:有一个容量为n的背包,有两种宝物,体积分别为S1,S2;价值为V1,V2。这两种宝物有无数种,现在向背包中塞宝物,问最多能装多少价值。
分析:可以很容易想到这个代码
for (int i = 0; i <= n / max(s1,s2); i++) { tmp = i * v1; ans = max(ans, tmp + ((n - i * s1) / s2) * v2); }
但是,如果max(s1,s2)很小的话,就会瞬间爆炸。
比如n有1073741824,但是max(s1,s2)==2,循环就到了亿级。
所以可以在考虑max(s1,s2)比较小的时候换一种暴力的方式。
直接考虑两种宝物性价比哪个高,暴力那个性价比高的即可。
if (s1 <= 100000) { if (s1 * v2 > s2 * v1) //第二个宝物性价比第一个宝物高
{ for (int i = 0; i < s2; i++) { tmp = i * v1; ans = max(ans, tmp + ((n - i * s1) / s2) * v2); } } else for (int i = 0; i < s1; i++) { tmp = i * v2; ans = max(ans, tmp + ((n - i * s2) / s1) * v1); } } }
当第二个宝物性价比比第一个宝物高时:
其实就是遍历取第一种宝物数量的暴力,可能取0个、1个、2个....s2-1个,这是未知的,所以需要通过暴力跑出来。
为什么不需要s2个,因为如果第一种取s2个,因为第二个宝物的性价比比第一个宝物高,所以取s2个第一宝物还不如取s1个第二宝物。
反之类似。
代码:
1 #include <set> 2 #include <map> 3 #include <list> 4 #include <cmath> 5 #include <queue> 6 #include <vector> 7 #include <bitset> 8 #include <string> 9 #include <cctype> 10 #include <cstdio> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 16 using namespace std; 17 18 typedef long long ll; 19 typedef unsigned long long ull; 20 #define inf (0x3f3f3f3f) 21 #define lnf (0x3f3f3f3f3f3f3f3f) 22 #define eps (1e-8) 23 int sgn(double a) {return a < -eps ? -1 : a < eps ? 0 : 1;} 24 25 //-------------------------- 26 27 28 29 int t; 30 ll s1, v1, s2, v2; 31 ll n; 32 33 void solve() { 34 scanf("%d", &t); 35 int s = 0; 36 while (t--) { 37 scanf("%lld%lld%lld%lld%lld", &n, &s1, &v1, &s2, &v2); 38 if (s1 < s2) { 39 swap(s1, s2); 40 swap(v1, v2); 41 } 42 ll tmp; 43 ll ans = 0; 44 if (s1 <= 100000) { 45 if (s1 * v2 > s2 * v1) { 46 for (int i = 0; i < s2; i++) { 47 tmp = i * v1; 48 ans = max(ans, tmp + ((n - i * s1) / s2) * v2); 49 } 50 } else { 51 for (int i = 0; i < s1; i++) { 52 tmp = i * v2; 53 ans = max(ans, tmp + ((n - i * s2) / s1) * v1); 54 } 55 } 56 printf("Case #%d: %lld ", ++s, ans ); 57 continue; 58 } 59 for (int i = 0; i <= n / s1; i++) { 60 tmp = i * v1; 61 ans = max(ans, tmp + ((n - i * s1) / s2) * v2); 62 } 63 printf("Case #%d: %lld ", ++s, ans ); 64 } 65 66 } 67 68 69 70 int main() { 71 72 #ifndef ONLINE_JUDGE 73 freopen("1.in", "r", stdin); 74 freopen("1.out", "w", stdout); 75 #endif 76 //iostream::sync_with_stdio(false); 77 solve(); 78 return 0; 79 }