题目
Description
小明在业余时间喜欢打电子游戏,不是星际和魔兽这些,是赛尔号一类的游戏。最近小明在玩一款新出的游戏,叫做■■■■■■■■。小明觉得游戏里自己的装备太垃圾了,每次都被大神虐,一怒之下充了■■元准备强化装备。
这个游戏中用于强化装备的道具叫做强化符文。有以下3 种:
1. 赋值强化符文,对某个装备使用这个符文以后,装备威力值会变为一个常数。因为这个功能很IMBA,可以让一个垃圾装备变得非常牛■,所以它在游戏里很稀有,市场上最多能见到一个。
2. 加法强化符文,对某个装备使用后,威力值加上一个常数。
3. 乘法强化符文,对某个装备使用后,威力值乘上一个常数。
市场上有M 个不同强化符文可以购买,小明有N 件装备准备强化,他只能购买K 个强化符文,然后以任意顺序使用这些符文,强化他的任意装备(一个装备可以不强化也可以强化多次)。根据游戏的设定,所有装备威力值乘积为总效果。请为他设计一个购买和强化方案,使强化后的所有装备总效果值最大。
由于小明RP 不太好,打BOSS 都不掉神装,所以他的装备不超过两件。
这个游戏中用于强化装备的道具叫做强化符文。有以下3 种:
1. 赋值强化符文,对某个装备使用这个符文以后,装备威力值会变为一个常数。因为这个功能很IMBA,可以让一个垃圾装备变得非常牛■,所以它在游戏里很稀有,市场上最多能见到一个。
2. 加法强化符文,对某个装备使用后,威力值加上一个常数。
3. 乘法强化符文,对某个装备使用后,威力值乘上一个常数。
市场上有M 个不同强化符文可以购买,小明有N 件装备准备强化,他只能购买K 个强化符文,然后以任意顺序使用这些符文,强化他的任意装备(一个装备可以不强化也可以强化多次)。根据游戏的设定,所有装备威力值乘积为总效果。请为他设计一个购买和强化方案,使强化后的所有装备总效果值最大。
由于小明RP 不太好,打BOSS 都不掉神装,所以他的装备不超过两件。
Input
第一行3 个正整数N;M;K, 含义见题面。
第二行N 个正整数Ai,表示他的每个装备的初始威力值。
第三行开始共M 行,每行两个正整数Type_i;Ci,描述一个强化符文。Type_i表示符文类型,1 表示赋值,2 表示加法,3 表示乘法。Ci 是对应的常数值。
第二行N 个正整数Ai,表示他的每个装备的初始威力值。
第三行开始共M 行,每行两个正整数Type_i;Ci,描述一个强化符文。Type_i表示符文类型,1 表示赋值,2 表示加法,3 表示乘法。Ci 是对应的常数值。
Output
一个数,表示最大的总效果值。由于这个数可能很大,请输出它的自然对数,保留3 位小数。
Sample Input
2 5 3
0 1
2 3
2 1
2 4
3 4
3 2
Sample Output
4.159
Data Constraint
对于20% 的数据,N = 1;
对于全部数据M,K ≤ 100;N ≤ 2,最多一个Type_i = 1。
输入数据中所有数不超过2000。
对于全部数据M,K ≤ 100;N ≤ 2,最多一个Type_i = 1。
输入数据中所有数不超过2000。
分析
-
出看这道题嗯,代码量很大
- 打了暴力,却忘了精度问题
- 我们首先要知道一个小知识:log(a*b)=log(a)+log(b)
- 这样乘法就解决了
- 然后就是一个DP,设f[i][j]为用了i个道具,有了价值为j的最大的第二个道具的值
- 转移方程就是
f[i+1][j]=max(f[i][j]+jia[i+1]*j,f[i+1][j]);
f[i+1][j+jia[i+1]]=max(f[i][j]+jia[i+1]*(sum[i]-j),f[i+1][j+jia[i+1]]); - 因为赋值的只有一个,所以我们只需要,枚举就好了
代码
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #define ll long long 7 using namespace std; 8 const int N=110; 9 int jia[N],che[N],sum[N],f[110][N*2000],maxs[N]; 10 double summ[N]; 11 double ans; 12 bool cmp(int a,int b){ 13 return a>b; 14 } 15 int main () 16 { 17 ios::sync_with_stdio(false); 18 int n,m,k; 19 cin>>n>>m>>k; 20 int x=0,y=0; 21 if (n==1) 22 cin>>x; 23 else 24 cin>>x>>y; 25 int cnt1=0,cnt2=0; 26 int fff=0; 27 for (int i=1,b,c;i<=m;i++) 28 { 29 cin>>b>>c; 30 if (b==1) 31 fff=c; 32 if (b==2) 33 jia[++cnt1]=c; 34 if (b==3) 35 che[++cnt2]=c; 36 } 37 sort(jia+1,jia+1+cnt1,cmp); 38 sort(che+1,che+1+cnt2,cmp); 39 sum[0]=x+y; 40 for (int i=1;i<=k;i++) 41 { 42 summ[i]=summ[i-1]+log(che[i]); 43 sum[i]=sum[i-1]+jia[i]; 44 } 45 if (n==1) 46 { 47 for(int i=0;i<=k;i++) 48 { 49 ans=max(ans,log(sum[min(i,cnt1)])+summ[min(k-i,cnt2)]); 50 if(i!=k&&fff) 51 ans=max(ans,log(sum[min(i,cnt1)])+summ[min(k-i-1,cnt2)]); 52 } 53 printf("%.3lf\n",ans); 54 return 0; 55 } 56 memset(f,0xcf,sizeof(f)); 57 f[0][x]=x*y; 58 for(int i=0;i<=cnt1;i++) 59 { 60 for(int j=x;j<=sum[i];j++) 61 { 62 f[i+1][j]=max(f[i][j]+jia[i+1]*j,f[i+1][j]); 63 f[i+1][j+jia[i+1]]=max(f[i][j]+jia[i+1]*(sum[i]-j),f[i+1][j+jia[i+1]]); 64 maxs[i]=max(maxs[i],f[i][j]); 65 } 66 } 67 for(int u=0;u<=k;u++) 68 ans=max(ans,log(maxs[min(u,cnt1)])+summ[min(k-u,cnt2)]); 69 if(fff) 70 { 71 k--; 72 sum[0]=fff+y; 73 for(int i=1;i<=k;i++) 74 sum[i]=sum[i-1]+jia[i]; 75 memset(f,0xcf,sizeof(f)); 76 memset(maxs,0,sizeof(maxs)); 77 f[0][fff]=fff*y; 78 for(int i=0;i<=k;i++) 79 { 80 for(int j=fff;j<=sum[i];j++) 81 { 82 f[i+1][j]=max(f[i][j]+jia[i+1]*j,f[i+1][j]); 83 f[i+1][j+jia[i+1]]=max(f[i][j]+jia[i+1]*(sum[i]-j),f[i+1][j+jia[i+1]]); 84 maxs[i]=max(maxs[i],f[i][j]); 85 } 86 } 87 for(int u=0;u<=k;u++) 88 ans=max(ans,log(maxs[u])+summ[k-u]); 89 sum[0]=x+fff; 90 for(int i=1;i<=k;i++) 91 sum[i]=sum[i-1]+jia[i]; 92 memset(f,0xcf,sizeof(f)); 93 memset(maxs,0,sizeof(maxs)); 94 f[0][x]=x*fff; 95 for(int i=0;i<=k;i++) 96 { 97 for(int j=x;j<=sum[i];j++) 98 { 99 f[i+1][j]=max(f[i][j]+jia[i+1]*j,f[i+1][j]); 100 f[i+1][j+jia[i+1]]=max(f[i][j]+jia[i+1]*(sum[i]-j),f[i+1][j+jia[i+1]]); 101 maxs[i]=max(maxs[i],f[i][j]); 102 } 103 } 104 for(int u=0;u<=k;u++) 105 ans=max(ans,log(maxs[u])+summ[k-u]); 106 } 107 printf("%.3lf",ans); 108 }