HDU 4091 Zombie’s Treasure Chest (不错的数论题)

题意:

给你一个体积V,第一种物品的体积价值s1,v1,第二种物品的体积价值s2,v2,物品都是任意个,问把两种物品放入V体积中最大的价值是多少。


解题思路:

设L = lcm(s1, s2),a = L/s1表示L体积下物品一的个数,b = L/s2表示L体积下物品二的个数,则最佳情况性价比低的那个物品个数必然不大它与L体积下的个数。所以有这个公式,如果res/L >= 1设res = V%L,设最佳情况体积为k*L + d (d <= res),必然可以减下物品多的那个的个数使得体积为L + d,也就是说体积为(V = k*L + res)最佳情况的多出来的那一部分总是可以和体积为L + res最佳情况多出来的那一部分对应。所以我只需要考虑L + res的最优解,这个可以直接枚举体积大的那个物品的数量求出,剩余的(k-1)*L我肯定是都放性价比较高的那个物品。


/* **********************************************
Author      : JayYe
Created Time: 2013-10-10 19:19:55
File Name   : JayYe.cpp
*********************************************** */

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef __int64 ll;

ll gcd(ll a, ll b) {
    return b ? gcd(b, a%b) : a;
}

ll lcm(ll a, ll b) {
    return a/gcd(a, b)*b;
}

int main() {
    int t, cas = 1;
    ll v, s1, s2, v1, v2;
    scanf("%d", &t);
    while(t--) {
        scanf("%I64d%I64d%I64d%I64d%I64d", &v, &s1, &v1, &s2, &v2);
        if(s1 < s2) swap(s1, s2), swap(v1, v2);
        printf("Case #%d: ", cas++);
        ll L = lcm(s1, s2);
        ll res = v%L;
        if(v/L == 0) {
            ll ans = 0;
            for(int i = 0;i <= res/s1; i++)
                ans = max(ans, i*v1 + (res - i*s1)/s2*v2);
            printf("%I64d\n", ans);
        }
        else {
            ll ans = 0;
            for(int i = 0;i <= (res + L)/s1; i++)
                ans = max(ans, i*v1 + (res + L - s1*i)/s2*v2);
            ans += (v - L)/L*max(L/s1*v1, L/s2*v2);
            printf("%I64d\n", ans);
        }
    }
    return 0;
}


你可能感兴趣的:(HDU 4091 Zombie’s Treasure Chest (不错的数论题))