【NOIP2011模拟9.7】雾雨魔理沙
2016-08-14 21:26
459 查看
Description
在幻想乡,雾雨魔理沙是住在魔法之森普通的黑魔法少女。话说最近魔理沙从香霖堂拿到了升级过后的的迷你八卦炉,她迫不及待地希望试试八卦炉的威力。在一个二维平面上有许多毛玉(一种飞行生物,可以视为点),每个毛玉具有两个属性,分值value和倍率mul。八卦炉发射出的魔法炮是一条无限长的直线形区域,可以视为两条倾斜角为α的平行线之间的区域,平行线之间的距离可以为任意值,如下图所示:
![](http://img.blog.csdn.net/20160814204135620)
蓝色部分上下两条长边之间就是这次八卦炉的攻击范围,在蓝色范围内的毛玉(红点)属于该此被击中的毛玉,如果一个毛玉刚好在边界上也视为被击中。毛玉击中以后就会消失,每次发射八卦炉得到分值是该次击中毛玉的分值和乘上这些毛玉平均的倍率,设该次击中的毛玉集合为S,则分值计算公式为:
Score = SUM{value[i] | i 属于 S} * SUM{mul[i] | i 属于 S} / |S|
其中|S|表示S的元素个数。魔理沙将会使用若干次八卦炉,直到把所有毛玉全部击中。任意两次攻击的范围均不重叠。最后得到的分值为每次攻击分值之和。现在请你计算出能够得到的最大分值。
Input
第1行:1个整数N,表示毛玉个数
第2..N+1行:每行四个整数x, y, value, mul,表示星星的坐标(x,y),以及value和mul
第N+2行:1个整数α,表示倾斜角角度,0°到180°
Output
第1行:1个实数,表示最大分值,保留三位小数
Sample Input
3
1 3 3 1
2 1 2 2
3 4 2 1
45
Sample Output
9.333
Data Constraint
Hint
【数据范围】
对于60%的数据:1 <= N <= 500
对于100%的数据:1 <= N <= 2,000
-10,000 <= x,y <= 10,000
1 <= value,mul <= 100
【注意】
π = 3.1415926
我们可以设一个F数组,设F[i]表示前i个毛玉所获得的最大贡献。
于是Dp方程便显而易见:
F[i]=MaxF[j]+∑value[k](j<k<=i)∗∑mul[k](j<k<=i)i−j
要注意:如果两个点进行排序的坐标相同,则这两个点始终是属于同一个区域的,不能分开。在枚举时需要特判。
有了上面那个思想,我们可以看出,当斜率为任意值时,仍然可以对当前节点进行排序。
我们计算过每个点的斜角为α的直线与y轴的交点,并按照这个交点的y坐标b进行排序。
为了大家方便,我就直接透露公式了 o((>ω< ))o
b=y-k*x;
(因为y=kx+b ,当x=0时,函数相交于y轴,即y=b)
a[i].b=−Angle∗a[i].x+a[i].y;
而
Angle=tan(Angle∗pi/180);
这条式子是怎么来的呢
由于我懒得画图,所以读者先脑补一下 o(╯□╰)o
设:直线与x轴的交点为(a,0)
根据tan=yx−a
所以可以转成
a=tan∗x−ytan
a=x−ytan
与y轴的类似。
之后直接dp即可。
时间复杂度为O(n2)
PS:这道题涉及到三角函数.
在这里给大家稍微普及一下三角函数蛤。。。
![](http://img.blog.csdn.net/20160814210941897)
设∠A为α。
sin(α)=ac
cos(α)=bc
tan(α)=ab
在幻想乡,雾雨魔理沙是住在魔法之森普通的黑魔法少女。话说最近魔理沙从香霖堂拿到了升级过后的的迷你八卦炉,她迫不及待地希望试试八卦炉的威力。在一个二维平面上有许多毛玉(一种飞行生物,可以视为点),每个毛玉具有两个属性,分值value和倍率mul。八卦炉发射出的魔法炮是一条无限长的直线形区域,可以视为两条倾斜角为α的平行线之间的区域,平行线之间的距离可以为任意值,如下图所示:
蓝色部分上下两条长边之间就是这次八卦炉的攻击范围,在蓝色范围内的毛玉(红点)属于该此被击中的毛玉,如果一个毛玉刚好在边界上也视为被击中。毛玉击中以后就会消失,每次发射八卦炉得到分值是该次击中毛玉的分值和乘上这些毛玉平均的倍率,设该次击中的毛玉集合为S,则分值计算公式为:
Score = SUM{value[i] | i 属于 S} * SUM{mul[i] | i 属于 S} / |S|
其中|S|表示S的元素个数。魔理沙将会使用若干次八卦炉,直到把所有毛玉全部击中。任意两次攻击的范围均不重叠。最后得到的分值为每次攻击分值之和。现在请你计算出能够得到的最大分值。
Input
第1行:1个整数N,表示毛玉个数
第2..N+1行:每行四个整数x, y, value, mul,表示星星的坐标(x,y),以及value和mul
第N+2行:1个整数α,表示倾斜角角度,0°到180°
Output
第1行:1个实数,表示最大分值,保留三位小数
Sample Input
3
1 3 3 1
2 1 2 2
3 4 2 1
45
Sample Output
9.333
Data Constraint
Hint
【数据范围】
对于60%的数据:1 <= N <= 500
对于100%的数据:1 <= N <= 2,000
-10,000 <= x,y <= 10,000
1 <= value,mul <= 100
【注意】
π = 3.1415926
The Solution
题目大意 Topic effect
平面上有若干个带权点,用倾斜角为α的直线将其分为若干部分,每部分可以得到一个分值,求一个最大得分。考察算法 Algorithm:
解析几何 动态规划Analysis
首先,要对于α为0或90°的情况进行特判,分别按照y坐标或x坐标排序,然后进行Dp我们可以设一个F数组,设F[i]表示前i个毛玉所获得的最大贡献。
于是Dp方程便显而易见:
F[i]=MaxF[j]+∑value[k](j<k<=i)∗∑mul[k](j<k<=i)i−j
要注意:如果两个点进行排序的坐标相同,则这两个点始终是属于同一个区域的,不能分开。在枚举时需要特判。
有了上面那个思想,我们可以看出,当斜率为任意值时,仍然可以对当前节点进行排序。
我们计算过每个点的斜角为α的直线与y轴的交点,并按照这个交点的y坐标b进行排序。
为了大家方便,我就直接透露公式了 o((>ω< ))o
b=y-k*x;
(因为y=kx+b ,当x=0时,函数相交于y轴,即y=b)
a[i].b=−Angle∗a[i].x+a[i].y;
而
Angle=tan(Angle∗pi/180);
这条式子是怎么来的呢
由于我懒得画图,所以读者先脑补一下 o(╯□╰)o
设:直线与x轴的交点为(a,0)
根据tan=yx−a
所以可以转成
a=tan∗x−ytan
a=x−ytan
与y轴的类似。
之后直接dp即可。
时间复杂度为O(n2)
PS:这道题涉及到三角函数.
在这里给大家稍微普及一下三角函数蛤。。。
设∠A为α。
sin(α)=ac
cos(α)=bc
tan(α)=ab
CODE
#include <cstdio> #include <iostream> #include <cmath> #include <algorithm> #include <cstring> #define fo(i,a,b) for (int i=a;i<=b;i++) #define fd(i,a,b) for (int i=a;i>=b;i--) #define N 2005 #define pi 3.1415926 #define INF 2147483647 using namespace std; int n; struct note { int x,y,v,m; double b; }a ; struct Record { int v,m; }Pre ; int b ; double Angle; double F ; bool cmp(note a,note b){return a.x<b.x;} bool cmp2(note a,note b){return a.b<b.b;} inline int read() { int x=0,w=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*w; } double Calc(int l,int r) { double x = Pre[r].v - Pre[l-1].v, y = Pre[r].m - Pre[l-1].m; return (double)x*y/(r-l+1); } int main() { freopen("data.in","r",stdin); n=read(); // scanf("%d",&n); fo(i,1,n) a[i].x=read(),a[i].y=read(),a[i].v=read(),a[i].m=read(); //scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].v,&a[i].m); scanf("%lf",&Angle); if (Angle==90) sort(a+1,a+n+1,cmp); else { Angle = tan((double) Angle * pi /180); // Angle = sin((double)Angle * pi / 180) / cos((double)Angle * pi / 180); fo(i,1,n) a[i].b = -Angle * a[i].x + a[i].y; sort(a+1,a+n+1,cmp2); } fo(i,1,n) { Pre[i].v += Pre[i-1].v + a[i].v; Pre[i].m += Pre[i-1].m + a[i].m; } fo(i,1,n) F[i] = -INF; F[0]=0; fo(i,1,n) fo(j,0,i-1) if (a[i].x == a[j].x && a[i].y == a[j].y) break; else F[i] = max(F[i],F[j] + Calc(j+1,i)); printf("%.3lf",F ); }
相关文章推荐
- 2555. 【NOIP2011模拟9.7】雾雨魔理沙 (Standard IO)
- Jzoj 2555. 【NOIP2011模拟9.7】雾雨魔理沙
- 2554. 【NOIP2011模拟9.7】帕秋莉·诺蕾姬 (Standard IO)
- jzoj 2553. 【NOIP2011模拟9.7】射命丸文
- jzoj 2554. 【NOIP2011模拟9.7】帕秋莉·诺蕾姬
- 2556. 【NOIP2011模拟9.7】伊吹萃香 (Standard IO)
- 2553. 【NOIP2011模拟9.7】射命丸文 (StandardIO)
- 【NOIP2011模拟9.7】射命丸文
- 2553. 【NOIP2011模拟9.7】射命丸文 (Standard IO)
- 【模拟】[NOIP2011普及组]数字反转
- NOIP 2011机器翻译(模拟)
- [noip 2011]选择客栈---模拟(?)
- jzoj 2541. 【NOIP2011模拟9.1】方格取数
- 【NOIP2011模拟9.1】直角三角形 (Standard IO)
- jzoj 2544. 【NOIP2011模拟9.3】作弊的发牌者
- 2568. 【NOIP2011模拟9.17】地铁建设 (Standard IO)
- 2570. 【NOIP2011模拟9.17】数字生成游戏 (Standard IO)
- 【NOIP2011模拟9.9】过河问题
- 贪心(模拟费用流):NOIP2011 观光公交
- 【NOIP2016提高A组模拟9.7】总结