uva 12325 - Zombie's Treasure Chest

题目大意:给定容量为v的背包,给定两种无限的物品,重量和价值分别为 s1,v1,s2,v2. 求背包可以容纳的最大的价值。但是输入都是带符号的32位二进制整数。


解题:刚看到题的时候想用背包来解,但是看到数据范围之后,是不可能的。首先,此题只要确定了其中一个物品的数量,则另外一个武平改装多少个也就确定了,所以说此题使用枚举方法。

使用枚举方法时,发现确定一个枚举量,此题肯定会超时。此题的枚举方法值得学习。

考虑到s1,s2都可能很大,或者很小,或者一个大一个小。当一个大一个小的时候,我们枚举大的那个,但是又会出现大的那个就很小。此时我们认为的设定一个上限(程序中设置的是1000000),当要枚举的那个的最大数量大于设定的值时,我们使用另一种枚举方法。另一种枚举方法为:当是s1*v2 < s2*v1时,说明相同的体积(s1*s2)情况下全部装第一种物品的价值最大(可以借用物理上的密度使思想来理解),这样的话,就发现最大枚举量是s1(枚举的是第二个物品的数量).(如果第二个物品的数量大于等于s1,则用另一个物品替代的话,肯定价值更大一些);反之也是一样的情况。


//
//  main.cpp
//  uva 12325 - Zombie's Treasure Chest
//
//  Created by XD on 15/7/29.
//  Copyright (c) 2015年 XD. All rights reserved.
//

#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
#define ll long long
using namespace std ;
int maxs = 1000000 ;


int main(int argc, const char * argv[]) {
  
    int casenum ;
    scanf("%d" ,&casenum) ;
    ll n  , s1 ,v1,s2,v2 ;
    int j = 0 ;
    while (casenum--) {
        ll asn = 0 ;
        scanf("%lld%lld%lld%lld%lld",&n,&s1,&v1,&s2,&v2) ;
        if(n / s1 <=maxs)
        {
        
            ll t = n / s1 ;
            for (int i = 0; i <= t ; i++) {
                ll t1 = (n - i * s1 ) / s2 ;
                ll tasn = i * v1 + t1 * v2 ;
                asn = asn > tasn?asn:tasn ;
            }
            
        }
        else if(n / s2 <=maxs)
        {
            ll t = n / s2 ;
            for (int i = 0; i <= t ; i++) {
                ll t1 = (n - i * s2 ) / s1 ;
                ll tasn = i * v2+ t1 * v1 ;
                asn = asn > tasn?asn:tasn ;
            }
        }
        else{
            if (s1*v2 < s2*v1) {
                //枚举s2
                for (int i = 0 ;i<s1 ; i++) {
                    
                    ll t1 = (n - i * s2 ) / s1 ;
                    ll tasn = i * v2 + t1 * v1 ;
                    asn = asn > tasn?asn:tasn ;
                }
            }
            else{
                for (int i = 0 ;i<s2 ; i++) {
                    
                    ll t1 = (n - i * s1 ) / s2 ;
                    ll tasn = i * v1 + t1 * v2 ;
                    asn = asn > tasn?asn:tasn ;
                }
            }
        }
        printf("Case #%d: %lld\n" ,++j , asn ) ;
    }
    
    
    
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值