• bzoj 2037: [Sdoi2008]Sue的小球——dp


    Description

    Sue和Sandy最近迷上了一个电脑游戏,这个游戏的故事发在美丽神秘并且充满刺激的大海上,Sue有一支轻便小巧的小船。然而,Sue的目标并不是当一个海盗,而是要收集空中漂浮的彩蛋,Sue有一个秘密武器,只要她将小船划到一个彩蛋的正下方,然后使用秘密武器便可以在瞬间收集到这个彩蛋。然而,彩蛋有一个魅力值,这个魅力值会随着彩蛋在空中降落的时间而降低,Sue要想得到更多的分数,必须尽量在魅力值高的时候收集这个彩蛋,而如果一个彩蛋掉入海中,它的魅力值将会变成一个负数,但这并不影响Sue的兴趣,因为每一个彩蛋都是不同的,Sue希望收集到所有的彩蛋。 然而Sandy就没有Sue那么浪漫了,Sandy希望得到尽可能多的分数,为了解决这个问题,他先将这个游戏抽象成了如下模型: 以Sue的初始位置所在水平面作为x轴。 一开始空中有N个彩蛋,对于第i个彩蛋,他的初始位置用整数坐标(xi, yi)表示,游戏开始后,它匀速沿y轴负方向下落,速度为vi单位距离/单位时间。Sue的初始位置为(x0, 0),Sue可以沿x轴的正方向或负方向移动,Sue的移动速度是1单位距离/单位时间,使用秘密武器得到一个彩蛋是瞬间的,得分为当前彩蛋的y坐标的千分之一。 现在,Sue和Sandy请你来帮忙,为了满足Sue和Sandy各自的目标,你决定在收集到所有彩蛋的基础上,得到的分数最高。

    Input

    第一行为两个整数N, x0用一个空格分隔,表示彩蛋个数与Sue的初始位置。 第二行为N个整数xi,每两个数用一个空格分隔,第i个数表示第i个彩蛋的初始横坐标。 第三行为N个整数yi,每两个数用一个空格分隔,第i个数表示第i个彩蛋的初始纵坐标。 第四行为N个整数vi,每两个数用一个空格分隔,第i个数表示第i个彩蛋匀速沿y轴负方向下落的的速度。

    Output

    一个实数,保留三位小数,为收集所有彩蛋的基础上,可以得到最高的分数。

    Sample Input

    3 0
    -4 -2 2
    22 30 26
    1 9 8

    Sample Output

    0.000


    数据范围:
    N < = 1000,对于100%的数据。 -10^4 < = xi,yi,vi < = 10^4
    ————————————————————————————————————————
    这道题是论文题 参见 徐源盛的对一类动态规划问题的讨论 网页链接
    并且这是明显属于当前状态对后面的影响只于当前的决策有关 那么
    f1[i][j]表示的是 已经收集了i-j的气球并且最终停在i f2[i][j]就是最终停在j 
    这个状态是可以n^2枚举的枚举长度 当前区间可以由长度-1的区间转移过来 这个看论文吧 解释很详细
    存一波代码QAQ
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using std::max;
    using std::sort;
    const int M=1e3+7;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int n,star,w[M][M];
    struct pos{int dis,h,v;}q[M];
    bool cmp(pos a,pos b){return a.dis<b.dis;}
    int f1[M][M],f2[M][M];
    int main(){
        n=read(); star=read();
        for(int i=1;i<=n;i++) q[i].dis=read();
        for(int i=1;i<=n;i++) q[i].h=read();
        for(int i=1;i<=n;i++) q[i].v=read();
        sort(q+1,q+1+n,cmp);
        w[1][n]=0;
        for(int len=n-1;len;len--){
            for(int i=1;i<=n-len+1;i++){
                int j=i+len-1;
                if(j+1<=n) w[i][j]=w[i][j+1]+q[j+1].v;
                else w[i][j]=w[i-1][j]+q[i-1].v;
            }
        }
        for(int i=1;i<=n;i++) f1[i][i]=f2[i][i]=q[i].h-abs(star-q[i].dis)*(w[i][i]+q[i].v);
        for(int len=2;len<=n;len++){
            for(int i=1;i<=n-len+1;i++){
                int j=i+len-1;
                f1[i][j]=q[i].h+max(f1[i+1][j]-(q[i+1].dis-q[i].dis)*w[i+1][j],f2[i+1][j]-(q[j].dis-q[i].dis)*w[i+1][j]);
                f2[i][j]=q[j].h+max(f1[i][j-1]-(q[j].dis-q[i].dis)*w[i][j-1],f2[i][j-1]-(q[j].dis-q[j-1].dis)*(w[i][j-1]));
            }
        }printf("%.3f
    ",1.0*max(f1[1][n],f2[1][n])/1000);
        return 0;
    }
    View Code
  • 相关阅读:
    用bash脚本统计代码行数
    Winform应用程序实现通用消息窗口
    文件管理工具“三剑客” #Everything #SpaceSniffer #Clover
    Jenkins pipeline:pipeline 语法详解
    Android studio安装教程
    恶意代码分析实战 shellcode分析 lab 191 192 193 整体来说 对汇编代码的分析要求较高 因为没法直接反编译为C代码看
    恶意代码分析实战 加壳与脱壳 lab 181 182 183 184 185 手动脱壳和自动脱壳操作
    恶意代码分析实战 IDA分析 lab 73 一个通过感染主机exe 修改kernel.dll为恶意dll的后门程序 要做清理的话 是很难的!
    恶意代码分析实战 隐蔽的恶意代码启动 lab121 122 123 124 进程注入、进程替换、hook procmon监控os api调用不行 数据分析还是要sysmon
    恶意代码分析实战 ollydbg使用来了 Lab 91 92 93
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7602136.html
Copyright © 2020-2023  润新知