http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1548&judgeId=202758
首先,样例都已经知道,不能狂买一种,可能要分开买,第一种x个,第二种y个。
抽象起来,这题可以表达成。设买了红的x个,蓝的y个。
则有:
x * Wr + y * Wb <= c 同时要使得Hr * x + Hb * y最大。
其实表达成这样没什么用,还是求不出。
分类如下:
①、当有一种物品的重量 >= sqrt(c)的时候,那么可以暴力枚举那种物品的个数,上限就是sqrt(c),不然就爆了总值了。
②、然后下面这种有点脑洞了。
看看单价,Hr / Wr 和 Hb / Wb。如果 Hr / Wr < Hb / Wb
则有Hr * Wb < Wr * Hb
那么假设我红的买了Wb个,这个时候,能买多少个蓝的呢》?
买了Wb个红的,用了Wb * Wr这么多钱。
然后就能买Wr个蓝的了。因为根据那条不等式,这样更划算,所以买红的个数不会超过Wb
所以暴力枚举买了多少个红的就好。
记得预防形成负数
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> void work() { LL c, hr, hb, wr, wb; cin >> c >> hr >> hb >> wr >> wb; if (wr < wb) { swap(wr, wb); swap(hr, hb); } if (wr >= (int)sqrt(c * 1.0)) { LL ans = 0; LL en = (LL)sqrt(c * 1.0) + 1; for (int i = 0; i <= en; ++i) { if (i * wr > c) break; ans = max(ans, i * hr + (c - i * wr) / wb * hb); } cout << ans << endl; return; } LL ans = 0; if (hr * wb < hb * wr) { for (int i = 0; i <= wb; ++i) { if (i * wr > c) break; ans = max(ans, i * hr + (c - i * wr) / wb * hb); } } else { for (int i = 0; i <= wr; ++i) { if (i * wb > c) break; ans = max(ans, i * hb + (c - i * wb) / wr * hr); } } cout << ans << endl; } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }