JZOJ 2555【NOIP2011模拟9.7】雾雨魔理沙 几何计算&动态规划

这道题是本人在训练中发现的,具有挺高的教学意义,因此做一下分析。

简化一下题目大意,是这样的:在一个二维平面上给出若干个点,你可以划出一个无限宽,但是与X轴的夹角为Alpha度的区间,此区间的收益为区间所覆盖的点的(分数和*倍数和/点数),求最大的收益和。(区间不能重叠)
这里写图片描述

乍一看,似乎无从下手,甚至想出了按斜率排序的处理。但是,仔细看一下,发现:如果从每个点出发做一条直线,且直线同时交X轴Alpha度,就能得到一个交点,如果选取的区间的边界覆盖了这个交点,不就刚好能被选到了吗?

于是乎,新的想法出炉了:
这里写图片描述
但是,新的问题又来了!怎么求落在X轴上的点呢?
我们都知道一次函数的公式:(Y=KX+B)
我们有点(x1,y1)和点(0,y2),Y=K*X1+B,0=K*X2+B, 移项得:
-B=K*X2,X2=-B/K! 也就是说,只要得出BK,就能得出落在X轴上点的位置。K可以用正切函数得到,K=Tan(Alpha*π/180)B也就等于(Y-K*X1)。很轻松地得出X2

求出落点后,判断下有没有落点重复的,合并(一个落点必须同时选或不选)。再进行DP就完成了。

CODE(由于楼主很懒,没有时间翻译成C,所以只贴上一段P)

uses math;
var
        x,y:array[1..2000]of longint;
        value,mul,sum1,sum2:array[0..2000]of longint;
        i,j,l,n,m,a,last:longint; k,b:real;
        poi:array[0..2000]of real;
        f:array[0..2000]of real;
        bz:array[1..2000]of boolean;
procedure sort(l,r:longint);
var
        i,j:longint; mid:real;
begin
        i:=l;j:=r;
        mid:=poi[(i+j) div 2];
        repeat
                while poi[i]<mid do inc(i);
                while poi[j]>mid do dec(j);
                if i<=j then
                begin
                        value[0]:=value[i];value[i]:=value[j];value[j]:=value[0];
                        poi[0]:=poi[i];poi[i]:=poi[j];poi[j]:=poi[0];
                        mul[0]:=mul[i];mul[i]:=mul[j];mul[j]:=mul[0];
                        inc(i);dec(j);
                end;
        until i>j;
        if i<r then sort(i,r);
        if j>l then sort(l,j);
end;
begin
        readln(n);
        for i:=1 to n do
                readln(x[i],y[i],value[i],mul[i]);
        readln(a);
        k:=tan(a*3.1415926/180);
        for i:=1 to n do
        begin
                b:=y[i]-k*x[i];
                poi[i]:=b;
        end;
        sort(1,n);
        last:=1;
        for i:=2 to n do
        begin
                if (poi[i]=poi[last]) then
                begin
                        inc(value[last],value[i]);
                        inc(mul[last],mul[i]);
                        value[i]:=0;
                        mul[i]:=0;
                        bz[i]:=true;
                end else
                        last:=i;
        end;
        sum1[1]:=value[1];
        sum2[1]:=mul[1];
        for i:=2 to n do
        begin
                sum1[i]:=sum1[i-1]+value[i];
                sum2[i]:=sum2[i-1]+mul[i];
        end;
        for i:=1 to n do
        for j:=1 to i do
                f[i]:=max(f[i],f[j-1]+(sum1[i]-sum1[j-1])*(sum2[i]-sum2[j-1])/(i-j+1));
        writeln(f[n]:0:3);
end.

Thanks For Watching.

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了python应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值