• 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;
    }
  • 相关阅读:
    测试思想-流程规范 关于预发布环境的一些看法
    Jenkins 开启用户注册机制及用户权限设置
    Jenkins 利用Dashboard View插件管理任务视图
    Loadrunner 脚本开发-从文件读取数据并参数化
    SVN SVN合并(Merge)与拉取分支(Branch/tag)操作简介
    测试思想-流程规范 SVN代码管理与版本控制
    Python 关于Python函数参数传递方式的一点探索
    接口自动化 基于python+Testlink+Jenkins实现的接口自动化测试框架[V2.0改进版]
    Python 解决Python安装包时提示Unable to find vcvarsall.bat的问题
    lintcode :链表插入排序
  • 原文地址:https://www.cnblogs.com/planche/p/8659533.html
Copyright © 2020-2023  润新知