YbtOJ NOIP2020 模拟赛 B 组 Day10 B. 开采矿物【dp】【思维】


题目:

传送门


题意:

一共有 n n n个地点,我们需要依次经过
一开始有一个耐久为 w w w的稿子
有两种地点,资源点和维护点
在这里插入图片描述


分析:

正着做非常头疼,因为会发现某个点的答案不是最优,但可能是最优方案中的一步
说白了,貌似存在有后效性
老谚语,正难则反,设 f i f_i fi表示 i ∼ n i\sim n in的最优解
这样设是因为我们原本的难处在于某个时刻的 p p p怎么求出来
可不妨将一开始的 w w w视为 1 1 1,最后答案 ∗ w *w w也是一样的
相应的,我们将在第 i i i点时的 p p p也视为 1 1 1,倒着推转移方程式,会有:
f i = m a x { f i + 1 , f i + 1 ∗ ( 1 − k % ) + x } f_i=max\{f_{i+1},f_{i+1}*(1-k\%)+x\} fi=max{fi+1,fi+1(1k%)+x}
对于维护点也差不多


代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
using namespace std;
inline LL read()
{
	LL s=0,f=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {s=s*10+c-'0';c=getchar();}
	return s*f;
}
double f[100005];
int t[100005],v[100005];
int main()
{
	freopen("exploit.in","r",stdin);
	freopen("exploit.out","w",stdout);
	int n=read(),k=read(),c=read();double w=read();
	for(int i=1;i<=n;i++) t[i]=read(),v[i]=read();
	for(int i=n;i>=0;i--)
	{
		if(t[i]==1) f[i]=max(f[i+1],f[i+1]*(1-0.01*k)+v[i]);
		else f[i]=max(f[i+1],f[i+1]*(1+0.01*c)-v[i]);
	}
	printf("%.2lf",f[1]*w);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值