JZOJ 5377. 【NOIP2017提高A组模拟9.19】开拓

Description

Description

Input

Input

Output

Output

Sample Input

5 50 50 10
1 10
1 20
2 10
2 20
1 30

Sample Output

375.00

Data Constraint

Data Constraint

Solution

  • 本题最大的瓶颈在于“当前钻头能力”,我们尝试不储存“当前钻头能力”。

  • F[i] 表示前 i 个星球的最优收入。但这很明显是不行的,因为当前钻头能力会影响到后面的过程。

  • 不严谨的说,当前钻头能力具有“后效性”。

  • 但是这个当前钻头能力对后程的影响无非就是乘上一个数值。

  • 就好像初始钻头能力是 w ,实际上你可以按 1 来做,最后再把 ans 乘上 w

  • 正难则反F[i] 表示第 in 个星球的最优收入,且假设从第 i 个星球开始时钻头能力是 1

  • 转移过程就变得简单:

  • 如果在第 i 个星球开采,那么第 in 个星球的初始钻头能力就是 1(10.01k)

  • 换句话说,就是: F[i+1](10.01k) 。所以:

    F[i]=Max{F[i+1],F[i+1](10.01k)+a[i]}

  • 对于维护型星球,大同小异,就系数和代价的正负而已。

  • 实际处理时数组也不用,用变量存储即可,时间复杂度 O(N)

Code

#include<cstdio>
using namespace std;
const int N=100001;
double ans;
int a[N];
bool b[N];
inline int read()
{
    int X=0,w=1; char ch=0;
    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
    return X*w;
}
inline double max(double x,double y)
{
    return x>y?x:y;
}
int main()
{
    int n=read();
    double k=read(),c=read(),w=read();
    k=1-0.01*k,c=1+0.01*c;
    for(int i=1;i<=n;i++) b[i]=read()==1,a[i]=read();
    for(int i=n;i;i--) ans=max(ans,b[i]?ans*k+a[i]:ans*c-a[i]);
    printf("%.2lf",ans*w);
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值