jzoj4245. 【五校联考6day2】er (B组——Day11)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SSL_Yyx/article/details/86696109

题目

Description

小明在业余时间喜欢打电子游戏,不是星际和魔兽这些,是赛尔号一类的游戏。最近小明在玩一款新出的游戏,叫做■■■■■■■■。小明觉得游戏里自己的装备太垃圾了,每次都被大神虐,一怒之下充了■■元准备强化装备。
这个游戏中用于强化装备的道具叫做强化符文。有以下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 是对应的常数值。

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。

解析

在这里插入图片描述

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int l2,l1,n,m,k,v[3],c;
long long sum[105],a[105],b[105],f[200000];
double ans,mul[105];

bool cmp(int a,int b){
	return a>b;
}

int main (){
	scanf("%d %d %d",&n,&m,&k);
    for(int i=1;i<=n;i++) 
		scanf("%d",&v[i]);
    for(int i=1;i<=m;i++){
    	int x,y;
       	scanf("%d %d",&x,&y);
       	if (x==1) c=y;
	   		else if (x==2) a[++l1]=y; 
	   			else b[++l2]=y;
    }
    sort(a+1,a+l1+1,cmp);
	for(int i=1;i<=l1;i++)
		sum[i]=sum[i-1]+a[i];
    sort(b+1,b+l2+1,cmp);
	for(int i=1;i<=l2;i++) 
		mul[i]=mul[i-1]+log(b[i]*1.0);
    if (n==1){
       	for(int i=0;i<=l1;i++){
          	if (i>k) break;
          	ans=max(ans,log(1.0*(sum[i]+v[1]))+mul[k-i]);
          	ans=max(ans,log(1.0*(c+sum[i]))+mul[k-i-1]);
       	}
       	return !printf("%.3lf",ans);
	}
		else {
			mul[0]=1;f[0]=1;
	    	for(int i=0;i<=l1;i++){
	       		if (i>k) break;
	       		for(int j=sum[l1];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&&f[sum[i]-j]>0) {
		         	ans=max(ans,log((sum[i]-j+v[1])*1.0)+log((j+v[2])*1.0)+mul[k-i]);
		    		ans=max(ans,log((sum[i]-j+v[1])*1.0)+log((j+c)*1.0)+mul[k-i-1]);
		    		ans=max(ans,log((sum[i]-j+c)*1.0)+log((j+v[2])*1.0)+mul[k-i-1]);
		      	}
   	 		}
		}
    printf("%.3lf",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/SSL_Yyx/article/details/86696109
今日推荐