zoj 3634 Bounty hunter

来源:互联网 发布:wing it jordan 编辑:程序博客网 时间:2024/05/21 09:24

题目链接:Bounty hunter


题目大意:

有一个人拥有X的钱,Y的能力,要从城市1走到n,在每个城市他可以选择花费 a[i]的钱提升1个单位的能力,也可以不提升。然后完成一个任务,可以获得 b[i]*当前能力的钱。

注意:可以花费实数单位的金钱,提升相应实数单位的能力,比如花费1.0,获得1.0/a[i]的能力。

问最终最多能够获得多少钱?

错解:

一个显然的想法就是我现在提升一个单位的能力的花费为 a[i],我的收益是 Σb[j] (j≥i)。只要后者大于前者就一定提升能力,那么收益一定是会变多的!

这个想法看起来很正确,收益不断的增加,但是有一个问题,加入我在i城市和i+1城市提升能力都会使收益增加,按照这个想法,一定先在 i提升,然后在 i+1提升。但是当 a[i]>>a[i+1]时,就是我在后者提升更划算,能够提升很多的能力,比都提升获得的能力值还要多。因为我在 i提升花掉了所有的钱,在 i+1的时候就没有太多的钱了。有了这个反例这个想法显然是错的。

正解:(我没想出来,想法来自别人)

关键点1:钱和攻击力没有关系。我的钱带来的收益和我的攻击力带来的收益可以分开考虑,似乎很合理!

关键点2:钱和收益成正比,能力和收益成正比。钱越多收益越多,能力越大收益越多!(应该能证明,但是我不会证!)

这样,我们可以用 atc[i]表示带着1的钱进入 i城市能获得的最大的收益,mny[i]表示带着1的能力进入城市 i能获得的最多的钱数

初始时:atc[n]=b[n],mny[n]=max(1.0,1.0/a[n]*b[n]);

转移:atc[i]=b[i]*mny[i+1]+atc[i+1];   mny[i]=max(mny[i+1],1.0/a[i]*atc[i]);

//#pragma comment(linker,"/STACK:102400000,102400000")#include<stdio.h>#include<iostream>#include<string.h>#include<math.h>#include<algorithm>#include<vector>#include<map>#include<set>#include<queue>#include<string>#define ll long long#define db double#define PB push_back#define lson k<<1#define rson k<<1|1using namespace std;const int N = 100005;db a[N],b[N];db atc[N],mny[N];int main(){#ifdef PKWV    freopen("in.in","r",stdin);#endif // PKWV    int n;    db x,y;    while(scanf("%d%lf%lf",&n,&x,&y)+1)    {        for(int i=1;i<=n;i++) scanf("%lf%lf",&a[i],&b[i]);        atc[n]=b[n],mny[n]=max(1.0,1.0/a[n]*b[n]);        for(int i=n-1;i>0;i--)        {            atc[i]=b[i]*mny[i+1]+atc[i+1];            mny[i]=max(mny[i+1],1.0/a[i]*atc[i]);        }        printf("%.2f\n",x*mny[1]+y*atc[1]);    }    return 0;}


0 0
原创粉丝点击