首页 > 代码库 > 1548 欧姆诺姆和糖果 分类暴力 + 数学

1548 欧姆诺姆和糖果 分类暴力 + 数学

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;
}
View Code

 

1548 欧姆诺姆和糖果 分类暴力 + 数学