题意:
ACdream的群主EOF女神(EndofFile)很喜欢玩打地鼠游戏,作为女神,肯定不能像正常人去玩这个看似普通的游戏。EOF女神站在直角坐标系的原点上,不移动。游戏开始后,某一时刻t[i]在坐标(x[i],y[i])处会出现一只地鼠,地鼠十分敏捷,只在这一个时刻出现,马上就消失,EOF作为女神,当然不屑于用锤子去打地鼠,她用念力组成的锤子去打地鼠(Orz…),由于功力有限,女神只有一个念力锤子,念力锤子的移动速度为每秒v个单位长度,并且对于某一只地鼠,即使地鼠出现的瞬间锤子打到了该坐标,地鼠仍然有p[i]概率会击中,一旦闪避成功,便会马上消失。EOF女神还有一项超能力:预知未来!女神一开始便知道所有地鼠的出现坐标,出现的时刻,甚至是击中的概率(Orrrrrrrrrrz)。女神想知道她整个游戏过程中打中地鼠个数的数学期望是多少?
(Note: 女神可以在0s的瞬间击打任意一个地鼠)
题解:这题感觉题意有点问题。。。dp[i]表示到第i个位置打地鼠个数的期望,提前是要根据时间排序一下。然后就是无脑dp。
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> #define B(x) (1<<(x)) using namespace std; typedef long long ll; typedef unsigned long long ull; const int oo = 0x3f3f3f3f; const ll OO = 0x3f3f3f3f3f3f3f3f; const double eps = 1e-9; #define lson rt<<1 #define rson rt<<1|1 void cmax(int& a, int b){ if (b>a)a = b; } void cmin(int& a, int b){ if (b<a)a = b; } void cmax(ll& a, ll b){ if (b>a)a = b; } void cmin(ll& a, ll b){ if (b<a)a = b; } void cmax(double& a, double b){ if (a - b < eps) a = b; } void cmin(double& a, double b){ if (b - a < eps) a = b; } void add(int& a, int b, int mod){ a = (a + b) % mod; } void add(ll& a, ll b, ll mod){ a = (a + b) % mod; } const ll MOD = 1000000007; const int maxn = 1100; double dp[maxn]; struct Node{ int x, y, t; double p; }a[maxn]; bool cmp(Node n1, Node n2){ return n1.t < n2.t; } bool ok(const Node &n1, const Node &n2, int v){ return ((n1.x - n2.x)*(n1.x - n2.x) + (n1.y - n2.y)*(n1.y - n2.y)) <= v*v*(n1.t - n2.t)*(n1.t - n2.t); } int main(){ //freopen("E:\\read.txt","r",stdin); int T, n, v; scanf("%d", &T); while (T--){ scanf("%d %d", &n, &v); for (int i = 1; i <= n; i++) scanf("%d %d %d %lf", &a[i].x, &a[i].y, &a[i].t, &a[i].p); sort(a + 1, a + 1 + n, cmp); fill(dp, dp + maxn, 0.0); for (int i = 1; i <= n; i++){ dp[i] = a[i].p; for (int j = 1; j < i; j++){ if (ok(a[j], a[i], v)) cmax(dp[i], dp[j] + a[i].p); } } double ans = 0; for (int i = 1; i <= n; i++)cmax(ans, dp[i]); printf("%.6lf\n", ans); } return 0; }