zoukankan      html  css  js  c++  java
  • 考试

    【问题描述】

    小 S 要参见一场考试,这场考试一共有 k 道题目。每道题目有分值 ??,难度 zi 和
    类型 si。这些题目一共有 m 中不同的类型。
    由于小 S 偏科严重,所以对不同类型的题目熟练度可能不同,在第 i 种类型的题
    目熟练度为 yi。
    为了简化问题,我们认为当小 S 以 y 的熟练度做难度为 z 分值为 a 的题目时,
    会获得 a ⋅ (1 − max (0,1 − ??)2) 的分数。
    众所周知,做题不顺利可能影响心态和发挥,在这里我们认为,如果小 S 在某一
    道题目的得分低于总分的 64%,那么接下来做题熟练度会下降。具体来说,接下来的
    第 i 道题熟练度会下降 ci%。每一道题只会受到之前最后一次分数低于 64% 的影响。
    (就是说如果第 t 道题的分数小于满分的 64%,那么第 t+i 道题的熟练度会下降 Ci%。
    同时,如果有多道题分数小于满分的 64%,只有最后一次会有影响。比如说第 1 道题分
    数小于 64%那么第 3(即 1+2)题会下降 C2%,接下来第 4 题又低于 64%那么第 5(即 4+1)
    题会下降 C1%。)
    根据目前的描述,已经可以确定出小 S 在每道题的得分了。但是小 S 有 n 瓶神
    奇的饮料,在做题时喝掉第 i 瓶饮料可以让这道题的熟练度提高 xi%。每瓶饮料只能
    在一道题喝,做一道题时可以喝多瓶饮料。
    熟练度的下降和上升是依次进行,每次都按当前的百分比计算。简单来说,就是在
    原来的熟练度上乘 1 ± u%。
    现在问小 S 的总分最高是多少。

    【输入格式】

    从输入文件 test.in 中读入数据。
    第一行三个整数n, m, k,分别表示饮料的瓶数、题目类型的数量和试题的数量。
    第二行 n 个整数 x1, x2, ⋯ , ??,表示饮料能带来的提升
    第三行 m 个整数 y1, ?2, ⋯ , ??,表示每种题目类型的熟练度。
    第四行 k − 1 个整数 c1, c2, ⋯ , ck−1,表示做题不顺利对之后熟练度的下降程度。
    接下来 k 行,每行三个整数 ai, si, zi,分别表示题目的分值、类型和难度。

    【输出格式】

    输出到文件 test.out 中。
    输出一行一个实数,表示答案。四舍五入后保留两位小数输出。

    【样例 1 输入】

    1 1 2
    10
    100
    50
    100 1 260
    100 1 200

    【样例 1 输出】

    2019 年非专业级软件能力认证提高级(第二轮) 第二次认证 考试(test) 第 3 页 共 8 页
    141.72

    【样例 1 解释】

    一共一瓶饮料,可以选择在做第一题或第二题时喝。
    如果在做第二题时喝:
    做第一题的能力为 100,得分为 100 × (1 − (1 −
    100
    260)2) = 62 22
    169。
    由于分数低于 64,所以第二题的能力会下降 50%,又由于饮料可以提高 10%,
    所以实际能力为 100 × 50% × 110% = 55。
    于是第二题的得分为 100 × (1 − (1 −
    55
    200)2) = 47 7
    16。
    总得分为 109 1535
    2704 分。
    可以类似计算出在选择在做第一题时喝的得分为 141 121
    169
    分,所以最高分为
    141 121
    169 分。


    思路

    • n==0时,暴力
    • n!=0时,状压DP
    • f[i][j][S]表示到第i题、上一次挂在第j题、喝的饮料状态为S的最大答案

    代码

    #include <iostream>
    #include <cstdio>
    #include <iomanip>
    #include <cstring>
    using namespace std;
    int n,m,k,y[12];
    double x[12],c[500005],f[105][105][1030],xx[1030];
    struct fdfdfd{double a,z;int s;}e[500005];
    double gread(double y,double z,double a){
    	double t=max(0.0,1-y/z);
    	return a*(1-t*t);
    }
    int main()
    {
    	scanf("%d%d%d",&n,&m,&k);//饮料的瓶数、题目类型的数量、试题的数量 
    	for(int i=1;i<=n;++i) scanf("%lf",&x[i]),x[i]=(100+x[i])/100;//饮料能带来的提升 
    	for(int i=1;i<=m;++i) scanf("%d",&y[i]);//每种题目类型的熟练度 
    	for(int i=1;i<k;++i) scanf("%lf",&c[i]),c[i]=(100-c[i])/100;//做题不顺利对之后熟练度的下降程度 
    	for(int i=1;i<=k;++i) scanf("%lf%d%lf",&e[i].a,&e[i].s,&e[i].z);//题目的分值、类型和难度 
    	if(n==0)
    	{
    		double ans=0;
    		for(int i=1,lastf=0;i<=k;++i)
    		{
    			double p=y[e[i].s]*(lastf?c[i-lastf]:1),soc=gread(p,e[i].z,e[i].a);
    			if(e[i].a*0.64>soc) lastf=i;
    			ans+=soc;
    		}
    		cout<<fixed<<setprecision(2)<<ans<<'
    ';
    		return 0;
    	}
    	xx[0]=1;
    	for(int i=1;i<1<<n;++i)
    		for(int j=0;j<n;++j)
    			if(i&1<<j) xx[i]=xx[i^1<<j]*x[j+1];//xx[a]表示喝饮料状态为a时,熟练度提高值
    	for(int i=1;i<=k;++i)
    		for(int j=0;j<=i;++j)
    			for(int s=0;s<1<<n;++s)f[i][j][s]=-1;
    	f[0][0][0]=0;
    	for(int i=1;i<=k;++i)
    		for(int j=0;j<i;++j)
    			for(int s=0;s<1<<n;++s)
    				for(int s2=s;;s2=(s2-1)&s)//枚举子集
    				{
    					if(f[i-1][j][s2]==-1)
    					{
    						if(!s2) break;
    						continue;
    					}
    					double p=y[e[i].s]*(!j?1:c[i-j])*xx[s2^s],soc=gread(p,e[i].z,e[i].a);
    					if(e[i].a*0.64>soc) f[i][i][s]=max(f[i][i][s],f[i-1][j][s2]+soc);
    					else f[i][j][s]=max(f[i][j][s],f[i-1][j][s2]+soc);
    					if(!s2) break;
    				}
    	double ans=0;
    	for(int i=0;i<=k;++i) ans=max(ans,f[k][i][(1<<n)-1]);
    	cout<<fixed<<setprecision(2)<<ans<<'
    ';
    	return 0;
    }
    
  • 相关阅读:
    OpenWrt VTun Client
    LibreSpeed install on centos
    信号频道带宽、符号率、速率对应关系
    DVB相关标准
    Cisco Switch STP
    TROUBLESHOOTING MULTICAST ROUTING
    企业ERP核心模型与云计算生态
    Istio介绍(1)
    ServiceMesh案例
    Jenkins流水线发布实现CICD到Kubernetes
  • 原文地址:https://www.cnblogs.com/wuwendongxi/p/13915687.html
Copyright © 2011-2022 走看看