P1412 经营与开发

P1412 经营与开发

题解

QWQ题外话(蒟蒻的心路历程):拿到这个题,这不DP吗!!然后开始DFS ----> 敲完开始考虑DP,正推退不动啊,头疼的P咋整啊 ----> 交上DFS代码----->爆零 

 

DP大法好啊

       考虑顺次走1~n 这些星球对吧,每个星球可以考虑采矿/修复,或者打酱油,那么一旦采矿/修复,就会改变收入,改变能力值 p ,所以说正推从 1~n 是不合适的,有后效性

 

  then give up  

正难则反啊!倒着推不就没有后效性了吗

解释一下:

假设你每个星球都开采,并且每个星球都是资源型,那么你最后的答案一定是这样:

  w * a1 + w*(1-0.01k) *a2 + w*(1-0.01k)*(1-0.01k) * a3 + w*(1-0.01k)*(1-0.01k)*(1-0.01k) * a4.....

(提取一下公因式) 

=w * ( a1 + a2*(1-0.01k) + a3*(1-0.01k)*(1-0.01k) + a4*(1-0.01k)*(1-0.01k)*(1-0.01k)......)

(秦九韶公式来一波)

=w * ( a1 + (1-0.01k) * ( a2 + (1-0.01k) * ( a3 + (1-0.01k) * ( a4 + (1-0.01k) * (......))))))

(方便起见我们用 kk 表示 (1-0.01k))

=w * ( a1 + kk * ( a2 + kk * ( a3 + kk * ( a4 + kk * (......))))))

 

so,你会发现:wow非常nice的秦九韶公式!!!

       其实你最终的答案并不一定是每个星球都要开采,因此可能会缺几项,但这并不影响,而且每个星球也并不一定都是资源型,还可能是维护型,这样的话无非是把  (1-0.01k) 变成 (1+0.01c) ,也不会有啥影响

 

所以我们发现从后往前推是不会有后效性的,因为秦九韶计算也是从里到外计算

那么就是从 n 往前枚举,f[ i ] 表示从 星球 i 出发到达星球 n 的最大收入,ans is f[ 1 ]

 

得到递推式:

注意区分不同的类型,不同类型的星球造成的影响不同

 

 

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;

inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

const int maxn=1e5+10;
int n,k,c,w;
int x[maxn],type[maxn];
double ans;
double f[maxn]; 

int main()
{
    n=read();k=read();c=read();w=read();
    for(int i=1;i<=n;i++)
    {
        type[i]=read();
        x[i]=read();
    }
    for(int i=n;i>0;i--)
    {
        if(type[i]==1) 
        f[i]=max(f[i+1],x[i]+f[i+1]*(1-0.01*k));
        else
        f[i]=max(f[i+1],-x[i]+f[i+1]*(1+0.01*c));
    }
    
    printf("%.2lf",f[1]*w);
    
    return 0;
}

 

posted @ 2019-07-11 09:44  晔子  阅读(131)  评论(0编辑  收藏  举报