一道看似dp实则暴力的题 Zombie's Treasure Chest

             Zombie's Treasure Chest

本题题意:有一个给定容量的大箱子,此箱子只能装蓝宝石和绿宝石,假设蓝绿宝石的数量无限,给定蓝绿宝石的大小和价值,要求是获得最大的价值

题解:本题看似是dp中的背包问题,但是由于数据量太大,用dp肯定会超时,所以只能寻找另外一种思路,可以用贪心加暴力,先求出两种宝石大小的最小公倍数com,然后将N/com-com,与N%comkanchengs看成是两个部分(想想应该明白)。将前一个部分,放入单位价值量最高的那个,对于后面那个部分直接将S1的数量从一枚举到最大的数量就可以了。(记得将除了例子数以外的数申明成longlong型的)

代码:

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<iostream>
 4 using namespace std;
 5 int n;
 6 long long N,S1,V1,S2,V2;
 7 
 8 long long com(long long a,long long b){
 9     long long t;
10     for(long long i=min(a,b);i>0;i--){
11         if(a%i==0&&b%i==0){
12             t=i;
13             break;
14         }
15     }
16     return a*b/t;
17 }
18 
19 int main(){
20     int cas=0;
21    // freopen("in.txt","r",stdin);
22 //    freopen("out.txt","w",stdout);
23     scanf("%d",&n);
24     while(n--){
25         scanf("%lld%lld%lld%lld%lld",&N,&S1,&V1,&S2,&V2);
26         long long lef;
27         long long comm=com(S1,S2);
28         long long w=0;
29         long long v=0;
30         if(comm<N){
31             lef=N%comm+comm;
32             comm=N-lef;
33         }
34         else{
35             lef=N;
36             comm=0;
37         }
38         v=max(comm/S1*V1,comm/S2*V2);
39         if(S2>S1){
40             swap(S1,S2);
41             swap(V1,V2);
42         }
43         long long va=0;
44         for(long long i=0;i<=lef/S1;i++){
45             va=max(va,i*V1+(lef-i*S1)/S2*V2);
46         }
47         v=v+va;
48         printf("Case #%d: %lld
",++cas,v);
49     }
50     return 0;
51 }

提供一个可以测试数据的网站:https://www.udebug.com/

原文地址:https://www.cnblogs.com/muziqiu/p/7307871.html