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

来源:互联网 发布:2015年进出口数据 编辑:程序博客网 时间:2024/04/30 07:04

题意:

给你一个体积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      : JayYeCreated Time: 2013-10-10 19:19:55File 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;}


原创粉丝点击