• JZOJ 4245. 【五校联考6day2】er


    题目

    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。

     

    分析

    • 出看这道题嗯,代码量很大

    • 打了暴力,却忘了精度问题
    • 我们首先要知道一个小知识: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
    ",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 }

     

     

    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    计算字符个数
    字符串最后一个单词的长度
    C++面试宝典
    给定三角形ABC和一点P(x,y,z),判断点P是否在ABC内,给出思路并手写代码
    N-皇后问题(N Queens)
    图着色算法详解(Graph Coloring)
    c++学习路线连接
    数据结构--经典排序算法
    5. 最长回文子串
    4. 寻找两个有序数组的中位数
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/10334757.html
Copyright © 2020-2023  润新知