跟省赛差不多的一道题,贪心+背包,
对于一个最小公倍数,肯定有最优解。
#include <iostream>
#include <cstdio>
#include <cstring>
#define LL __int64
using namespace std;
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;
}
LL getmax(LL n,LL s1,LL v1,LL s2,LL v2)
{
int i;
LL maxx=0;
for(i=0;i<=n/s1;i++)
{
if(i*v1+(n-i*s1)/s2*v2 > maxx)
{
maxx=i*v1+(n-i*s1)/s2*v2;
}
}
return maxx;
}
int main()
{
int cas,k;
LL tmp,num,res;
LL n,s1,v1,s2,v2;
scanf("%d", &cas);
for(k=1;k<=cas;k++)
{
scanf("%I64d%I64d%I64d%I64d%I64d",&n,&s1,&v1,&s2,&v2);
tmp=lcm(s1,s2);
num=n/tmp;
n%=tmp;
//注意此处如果只背包余数的话不一定是最优解的,
if(num)
{
num--;
n+=tmp;
}
res=max((num)*(tmp/s1)*v1, (num)*(tmp/s2)*v2);
if(s2>s1)
{
res+=getmax(n,s2,v2,s1,v1);
}else{
res+=getmax(n,s1,v1,s2,v2);
}
printf("Case #%d: %I64d\n",k,res);
}
return 0;
}