zoukankan      html  css  js  c++  java
  • P1412 经营与开发

    题目描述

    4X概念体系,是指在PC战略游戏中一种相当普及和成熟的系统概念,得名自4个同样以“EX”为开头的英语单词。

    eXplore(探索)

    eXpand(拓张与发展)

    eXploit(经营与开发)

    eXterminate(征服)

    ——维基百科

    今次我们着重考虑exploit部分,并将其模型简化:

    你驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞过n个星球。

    星球笼统的分为2类:资源型和维修型。(p为钻头当前能力值)

    1.资源型:含矿物质量a[i],若选择开采,则得到a[i]*p的金钱,之后钻头损耗k%,即p=p*(1-0.01k)

    2.维修型:维护费用b[i],若选择维修,则支付b[i]*p的金钱,之后钻头修复c%,即p=p*(1+0.01c)

    注:维修后钻头的能力值可以超过初始值(你可以认为是翻修+升级)

    金钱可以透支。

    请作为舰长的你仔细抉择以最大化收入。

    输入输出格式

    输入格式:

    第一行4个整数n,k,c,w。

    以下n行,每行2个整数type,x。

    type为1则代表其为资源型星球,x为其矿物质含量a[i];

    type为2则代表其为维修型星球,x为其维护费用b[i];

    输出格式:

    一个实数(保留2位小数),表示最大的收入。

    输入输出样例

    输入样例#1: 复制
    5 50 50 10
    1 10
    1 20
    2 10
    2 20
    1 30
    
    输出样例#1: 复制
    375.00

    说明

    【数据范围】

    对于30%的数据 n<=100

    另有20%的数据 n<=1000;k=100

    对于100%的数据 n<=100000; 0<=k,c,w,a[i],b[i]<=100;保证答案不超过10^9

    先上30分的代码(三维数组空间开不了那么大)

    三维

    f(i,j,k)代表前i个,开采j个,维护k个的最大价值

    设p1,p2为那两个固定系数

    t=1

    f(i,j,k)=max(f(i-1,j,k),f(i-1,j-1,k)+p1^(j-1)*p2^k*a[i])

    t=2

    f(i,j,k)=max(f(i-1,j,k),f(i-1,j,k-1)+p1^j*p2^(k-1)*a[i])

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define inf 2147483647
    const ll INF = 0x3f3f3f3f3f3f3f3fll;
    #define ri register int
    template <class T> inline T min(T a, T b, T c)
    {
        return min(min(a, b), c);
    }
    template <class T> inline T max(T a, T b, T c)
    {
        return max(max(a, b), c);
    }
    template <class T> inline T min(T a, T b, T c, T d)
    {
        return min(min(a, b), min(c, d));
    }
    template <class T> inline T max(T a, T b, T c, T d)
    {
        return max(max(a, b), max(c, d));
    }
    #define pi acos(-1)
    #define me(x, y) memset(x, y, sizeof(x));
    #define For(i, a, b) for (int i = a; i <= b; i++)
    #define FFor(i, a, b) for (int i = a; i >= b; i--)
    #define mp make_pair
    #define pb push_back
    const int maxn = 100005;
    #define mod 100003
    const int N=200;
    
    // name*******************************
    double f[N][N][N];
    double p1,p2;
    int n;
    double k,c,w;
    int t[N];
    double a[N],b[N];
    double ans=0;
    int s1[N];
    int s2[N];
    // function******************************
    double qmul(double a,int b)
    {
        double base=a;
        double ans=1;
        while(b)
        {
            if(b&1)
                ans*=base;
            base*=base;
            b>>=1;
        }
        return ans;
    }
    
    //***************************************
    int main()
    {
    //    freopen("test.txt","r",stdin);
        cin>>n>>k>>c>>w;
        For(i,1,n)
        {
            s1[i]=s1[i-1];
            s2[i]=s2[i-1];
            cin>>t[i];
            if(t[i]==1)
            {
                cin>>a[i];
                s1[i]++;
            }
            else
            {
                cin>>b[i];
                s2[i]++;
            }
        }
        p1=1-0.01*k;
        p2=1+0.01*c;
        fill(&f[0][0][0],&f[N-1][N-1][N-1],-inf);
    
        f[0][0][0]=0;
        For(i,1,n)
        {
            For(j,0,s1[i])
            {
                For(k,0,s2[i])
                {
                    f[i][j][k]=f[i-1][j][k];
                    if(t[i]==1&&j>=1)
                        f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k]+qmul(p1,j-1)*qmul(p2,k)*a[i]);
                    if(t[i]==2&&k>=1)
                        f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]-qmul(p1,j)*qmul(p2,k-1)*b[i]);
                    ans=max(ans,f[i][j][k]);
    //                cout<<i<<","<<j<<","<<k<<":"<<f[i][j][k]<<endl;
                }
            }
        }
        printf("%.2f",ans*w);
        return 0;
    }
    View Code

    再看一维神奇代码

    逆着走,就能压成一维了!!!

    记最终答案为ans,其实对于每个星球不管是维修还是资源型,都可以把对钻头的改变度记作一个常数k,而且k是有后效性的。

    我们先具一个i=4的例子,

    ans=w*k1*a1+w*k1*k2*a2+w*k1*k2*k3*a3+w*k1*k2*k3*k4*a4,

    即ans=w*(k1*a1+k1*k2*a2+k1*k2*k3*a3+k1*k2*k3*a4),

    进一步提公因式就是ans=w*(k1*(a[1]+k2*(a[2]+k3*(a[3]+k4*a[4]))))

    所以我们发现从最里面往外面走是最好的,也就是逆着推,真特么神奇

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define inf 2147483647
    const ll INF = 0x3f3f3f3f3f3f3f3fll;
    #define ri register int
    template <class T> inline T min(T a, T b, T c)
    {
        return min(min(a, b), c);
    }
    template <class T> inline T max(T a, T b, T c)
    {
        return max(max(a, b), c);
    }
    template <class T> inline T min(T a, T b, T c, T d)
    {
        return min(min(a, b), min(c, d));
    }
    template <class T> inline T max(T a, T b, T c, T d)
    {
        return max(max(a, b), max(c, d));
    }
    #define pi acos(-1)
    #define me(x, y) memset(x, y, sizeof(x));
    #define For(i, a, b) for (int i = a; i <= b; i++)
    #define FFor(i, a, b) for (int i = a; i >= b; i--)
    #define mp make_pair
    #define pb push_back
    const int maxn = 100005;
    #define mod 100003
    const int N=100005;
    
    // name*******************************
    int n;
    double f[N];
    double k,c,w;
    int t[N];
    double a[N],b[N];
    double ans=-inf;
    // function******************************
    
    
    //***************************************
    int main()
    {
    //    freopen("test.txt","r",stdin);
    
        scanf("%d%lf%lf%lf",&n,&k,&c,&w);
        For(i,1,n)
        {
            scanf("%d",&t[i]);
            if(t[i]==1)
                scanf("%lf",&a[i]);
            else
                scanf("%lf",&b[i]);
        }
        double p1=1-0.01*k;
        double p2=1+0.01*c;
        For(i,0,n)
        f[i]=-inf;
        f[n+1]=0;
        FFor(i,n,1)
        {
            if(t[i]==1)
                f[i]=max(f[i+1],f[i+1]*p1+a[i]);
            else
                f[i]=max(f[i+1],f[i+1]*p2-b[i]);
        }
        printf("%.2f",f[1]*w);
    
        return 0;
    }
  • 相关阅读:
    2020总结来了,文末有福利
    CentOS 用户请关注,你期待的 CentOS Linux 9 再也不会来了
    全球最好的10款波尔多葡萄酒,拉菲居然垫底
    eth以太坊合约开发工具集
    html格式的文字去掉html tag转为纯text文字
    如何隐藏X-Powered-By
    aiXcoder3.0呼之欲出,代码补全 AI,带你进入「个性化智能编程时代」
    windows故障群集修改心跳网卡【原创】
    keepalived非争抢机制不生效报错Received lower prio advert, forcing new election
    MySQL主从复制,启动slave时报错1872 Slave failed to initialize relay log info structure from the repository
  • 原文地址:https://www.cnblogs.com/planche/p/8659533.html
Copyright © 2011-2022 走看看