题目大意
给出N件装备(N<=2),有M种符文,可以选择K种符文
1、 赋值强化符文,将其中一件装备的威力值直接变为ci(最多只有1个)
2、 加法强化符文,将其中一件装备的威力值加上ci
3、 乘法强化符文,将其中一件装备的威力值乘上ci
现在可以任意使用符文强化装备,所有装备威力值乘积为总效果。
求总效果值最大,并输出其自然对数
题目解析
首先,log(a*b)=log(a)+log(b)
因为赋值强化符文最多只有一个,可以枚举它用不用,并且肯定是最优先使用的
首先应清楚是先加后乘才能是效果值最大,所以先排好序,计算前缀和
当 N=1 时,枚举加法符文,其余的就是乘法符文了,赋值符文判断一下就可以了
当 N=2 时,乘法符文和N=1的情况相同,主要是计算只用加法符文时,两个装备威力值,乘法符文到最后怎么用都行
除了枚举选多少个加法符文外,还需要考虑如何分到两个装备上
因为只有两个装备,所以求出给第一个装备分的数值为 x ,那么另一个装备的威力值也就确定了
枚举其中一个装备的威力值就可以用背包来解决
代码
#include<bits/stdc++.h>
using namespace std;
int n,m,k,l,r,type,c,fuz;
int plu[105],mul[105],sum[105],f[200005];
double qzh[105],ans;
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
cin>>n>>m>>k>>l;
if(n==2) cin>>r;
for(int i=1;i<=m;i++)
{
cin>>type>>c;
if(type==1) fuz=c;
else if(type==2) plu[++plu[0]]=c;
else if(type==3) mul[++mul[0]]=c;
}
sort(plu+1,plu+1+plu[0],cmp);
sort(mul+1,mul+1+mul[0],cmp);
for(int i=1;i<=mul[0];i++)
qzh[i]=qzh[i-1]+log(mul[i]);
for(int i=1;i<=plu[0];i++)
sum[i]+=sum[i-1]+plu[i];
if(n==1)
for(int i=0;i<=min(k,plu[0]);i++)
{
if(k-i>=0) ans=max(ans,log(sum[i]+l)+qzh[k-i]);
if(k-i-1>=0&&fuz!=0) ans=max(ans,log(sum[i]+fuz)+qzh[k-i-1]);
}
else
{
f[0]=1;
for(int i=0;i<=min(k,plu[0]);i++)
{
for(int j=sum[plu[0]];j>=(sum[i]-sum[i-1]);j--)
f[j]=max(f[j],f[j-(sum[i]-sum[i-1])]);
for(int j=0;j<=sum[i];j++)
if(f[j]>0)
{
ans=max(ans,log(l+j)+log(r+sum[i]-j)+qzh[k-i]);
if(k-i-1>=0&&fuz!=0)
{
ans=max(ans,log(fuz+j)+log(r+sum[i]-j)+qzh[k-i-1]);
ans=max(ans,log(l+j)+log(fuz+sum[i]-j)+qzh[k-i-1]);
}
}
}
}
cout<<fixed<<setprecision(3)<<ans;
return 0;
}