【BZOJ2244】【SDOI2011】拦截导弹
来源:互联网 发布:无印良品淘宝旗舰店 编辑:程序博客网 时间:2024/05/17 01:02
Description
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度、并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于前一发的高度,其拦截的导弹的飞行速度也不能大于前一发。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
在不能拦截所有的导弹的情况下,我们当然要选择使国家损失最小、也就是拦截导弹的数量最多的方案。但是拦截导弹数量的最多的方案有可能有多个,如果有多个最优方案,那么我们会随机选取一个作为最终的拦截导弹行动蓝图。
我方间谍已经获取了所有敌军导弹的高度和速度,你的任务是计算出在执行上述决策时,每枚导弹被拦截掉的概率。
Input
第一行包含一个正整数
下面 行按顺序给出了敌军所有导弹信息:
第
Output
输出包含两行。
第一行为一个正整数,表示最多能拦截掉的导弹数量;
第二行包含
Sample Input
43 304 406 603 30
Sample Output
20.33333 0.33333 0.33333 1.00000
数据规模和约定
对于
均匀分布着约
均匀分布着约
题解
一道综合数据结构与 DP 的好题。
首先,题目要求求一个最长二维不上升序列的长度,这可以通过 CDQ 分治 + 树状数组解决。转移方式同
然后,题目要求求出随机选取一个最初不上升子序列,每个点被选中的概率。这可以通过类似 LIS 计数的方法解决。也是和一维的情况类似,可以在dp的过程中记录以当前位置结束的最长不上升子序列的数量
总复杂度
My Code
#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <cstdio>using namespace std;typedef long long ll;struct node { int x, y, id, ans;} d[100005], t[100005];int n;int h[100005], c[100005];int th[100005], tc[100005];int bit[1000005];double cnt[1000005];inline int lowbit(int x) { return x & -x;}inline void add(int x, int w, double v) { for(int i = x; i <= n; i += lowbit(i)) { if(bit[i] == w) { cnt[i] += v; } else if(bit[i] < w) { bit[i] = w; cnt[i] = v; } }}inline int qmax(int x) { int sum = 0; for(int i = x; i; i -= lowbit(i)) { if(bit[i] > sum) sum = bit[i]; } return sum;}inline double qsum(int x, int mx) { double sum = 0; for(int i = x; i; i -= lowbit(i)) { if(bit[i] == mx) sum += cnt[i]; } return sum;}inline void del(int x) { for(int i = x; i <= n; i += lowbit(i)) { cnt[i] = 0; bit[i] = 0; }}int f[2][100005];double g[2][100005];int cmp1(node a, node b) { return a.x < b.x;}int cmp2(node a, node b) { return a.id < b.id;}void cdq1(int l, int r) { if(l == r) return; int mid = (l + r) >> 1; cdq1(l, mid); int p = l, q = mid + 1; sort(d + l, d + mid + 1, cmp1); sort(d + mid + 1, d + r + 1, cmp1); for(int i = l; i <= r; i ++) { if((p <= mid && d[p].x <= d[q].x) || q > r) { add(d[p].y, f[0][d[p].id], g[0][d[p].id]); p++; } else { int tmax = qmax(d[q].y); if(f[0][d[q].id] < tmax + 1) { f[0][d[q].id] = tmax + 1; g[0][d[q].id] = qsum(d[q].y, tmax); } else if(f[0][d[q].id] == tmax + 1) { g[0][d[q].id] += qsum(d[q].y, tmax); } q++; } } for(int i = l; i <= mid; i ++) { del(d[i].y); } sort(d + l, d + r + 1, cmp2); cdq1(mid + 1, r); sort(d + l, d + r + 1, cmp2);}void cdq2(int l, int r) { if(l == r) return; int mid = (l + r) >> 1; cdq2(l, mid); int p = l, q = mid + 1; sort(d + l, d + mid + 1, cmp1); sort(d + mid + 1, d + r + 1, cmp1); for(int i = l; i <= r; i ++) { if((p <= mid && d[p].x <= d[q].x) || q > r) { add(d[p].y, f[1][d[p].id], g[1][d[p].id]); p++; } else { int tmax = qmax(d[q].y); if(f[1][d[q].id] < tmax + 1) { f[1][d[q].id] = tmax + 1; g[1][d[q].id] = qsum(d[q].y, tmax); } else if(f[1][d[q].id] == tmax + 1) { g[1][d[q].id] += qsum(d[q].y, tmax); } q++; } } for(int i = l; i <= mid; i ++) { del(d[i].y); } sort(d + l, d + r + 1, cmp2); cdq2(mid + 1, r); sort(d + l, d + r + 1, cmp2);}int main() { scanf("%d", &n); for(int i = 1; i <= n; i ++) { scanf("%d%d", &h[i], &c[i]); th[i] = h[i]; tc[i] = c[i]; } sort(th + 1, th + n + 1); sort(tc + 1, tc + n + 1); for(int i = 1; i <= n; i ++) { h[i] = lower_bound(th + 1, th + n + 1, h[i]) - th; c[i] = lower_bound(tc + 1, tc + n + 1, c[i]) - tc; d[i].x = n - h[i] + 1, d[i].y = n - c[i] + 1; d[i].id = i; } for(int i = 1; i <= n; i ++) f[0][i] = f[1][i] = g[0][i] = g[1][i] = 1; cdq1(1, n); for(int i = 1; i <= n; i ++) { d[i].x = h[n - i + 1], d[i].y = c[n - i + 1]; d[i].id = i; } cdq2(1, n); int ans = 0; for(int i = 1; i <= n; i ++) { ans = max(ans, f[0][i]); } printf("%d\n", ans); double sum = 0; for(int i = 1; i <= n; i ++) { if(f[0][i] == ans) sum += g[0][i]; } for(int i = 1; i <= n; i ++) { if(f[0][i] + f[1][n - i + 1] - 1 != ans) printf("%.5lf ", 0.0); else printf("%.5lf ", double(g[0][i]) * double(g[1][n - i + 1]) / sum); } return 0;}
- 【SDOI2011】【BZOJ2244】拦截导弹
- 【bzoj2244】[SDOI2011]拦截导弹
- 【BZOJ2244】【SDOI2011】拦截导弹
- BZOJ2244 & Codevs1822 [SDOI2011]拦截导弹
- [BZOJ2244][SDOI2011]拦截导弹(DP+CDQ分治)
- [BZOJ2244][SDOI2011]拦截导弹(dp+cdq分治)
- BZOJ 2244 [SDOI2011] 拦截导弹
- bzoj 2244 [SDOI2011]拦截导弹
- bzoj 2244: [SDOI2011]拦截导弹
- bzoj 2244: [SDOI2011]拦截导弹
- 【bzoj】2244: [SDOI2011]拦截导弹【cdq分治】
- [CDQ分治] BZOJ 2244 [SDOI2011]拦截导弹
- BZOJ 2244 SDOI2011 拦截导弹 CDQ分治/二维树状数组
- bzoj 2244: [SDOI2011]拦截导弹 (CDQ分治+DP)
- [BZOJ]2244: [SDOI2011]拦截导弹 DP+CDQ分治+树状数组
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 有关分布式 MySQL 数据库中间件 MySQLDA,一文为你深入介绍~
- 你到底能有多聪明(智力)
- android 4.0.3 设置时间无法更新到RTC
- vue+ssr+axios
- Java与CSP数据兼容之一:Java兼容CSP导出的RSA公钥数据
- 【BZOJ2244】【SDOI2011】拦截导弹
- 【Scikit-Learn 中文文档】特征选择
- ubuntu下的caffe安装
- 学术论文地址总结
- React学习笔记_按需加载
- Spark算子:RDD基本转换操作(1)–map、flagMap、distinct
- 二叉树的遍历方法及递归实现
- 服务端开发之MySql数据库问题记录
- react-native + redux 实践