Description

偶然间,chnlich 发现了他小时候玩过的一个游戏“魂斗罗”,于是决定怀旧。但是这是一个奇怪的魂斗罗 MOD。
有 N 个关卡,初始有 Q 条命。
每通过一个关卡,会得到 u 分和1条命,生命上限为 Q。其中 u=min(最近一次连续通过的关数,R)。
若没有通过这个关卡,将会失去1条命,并进入下一个关卡。
当没有生命或没有未挑战过的关卡时,游戏结束,得到的分数为每关得到的分数的总和。
由于 chnlich 好久不玩这个游戏了,每条命通过每个关卡的概率均为p(0<=p<=1),原先 chnlich 的最高分纪录是 S。
现在 chnlich 想要知道,当 p 至少为多少时,chnlich 期望获得的总分数能够超过原先的最高分。
(本题题意可能有些难理解所以给了样例)

Input

输入共一行,分别表示整数 N,整数 R,整数 Q,原先的最高分整数 S。

Output

输出共一行,若不存在这样的 p,输出"Impossible."(不包含引号),否则输出 p(保留6位小数)。

Sample Input

【样例输入一】
4 2 1 5

【样例输入二】
12 3 2 12

Sample Output

【样例输出一】
0.880606

【样例输出二】
0.687201

Data Constraint

【数据说明】
对于\(20%\)的数据,\(N<=15\)
对于\(50%\)的数据,\(N<=10000\)
对于\(100%\)的数据,\(N<=10^8,1<=R<=20,1<=Q<=5\),保证\(S\)是一个可能出现的分数。

【补充说明】
例如,当 N=12,R=3,Q=2时
第一关:未通过 u=0 获得分数0 总分为0 剩余生命1
第二关:通过 获得分数1 总分为1 剩余生命2
第三关:通过 获得分数2 总分为3 剩余生命2
第四关:通过 获得分数3 总分为6 剩余生命2
第五关:通过 获得分数3 总分为9 剩余生命2
第六关:未通过 获得分数0 总分为9 剩余生命1
第七关:通过 获得分数1 总分为10 剩余生命2
第八关:未通过 获得分数0 总分为10 剩余生命1
第九关:未通过 获得分数0 总分为10 剩余生命0
游戏结束 总分为10
这是 chnlich 游戏的一种可能性

Solution

看完题后想到了\(概率DP\),状态转移方程很容易得出,但是不好求答案。最后弃了。
正解是\(二分答案+概率DP+矩乘优化\)。
我们先二分一个\(p\),然后对于这个\(p\)做\(DP\)。
设\(f[i][j][k]\)表示玩到第\(i\)关,当前\(u\)为\(j\),\(k\)连胜的概率。
那么我们很容易的到转移方程(胜和负)
而答案就是所有的\(f[i][j][k]*p*min(j+1,r)\)的和,比较S再二分即可。
这样\(O(log(1000000)*n*r*q)\),50分到手。
然后我们考虑矩乘优化。
我们将\(p*q\)的数组编号,\(1\)~\(len-1\)
我们设f[i][j]表示从i状态转移到j状态的概率。
而len的那一列表示答案。先求出初始矩阵,然后转移即可。(详见标)
优化:我们可以发现,当\(u>=q - 1\)的时候,它的生命一定是满的,所以最多有大概42种状态。
那些多余状态不考虑的话,\(len\)将会大大减少。
记得注意精度问题!!!

Code

#include <cstdio>
#include <cstring>
#define db double
#define mem(a, x) memset(a, x, sizeof a)
#define fo(x, a, b) for (int x = a; x <= b; x++)
using namespace std;
int n, R, Q, S, len = 0, num[21][6];
db l = 0.0, r = 1.0, mid;struct matrix
{db a[45][45];matrix operator *(const matrix &b){matrix c;mem(c.a, 0);fo(k, 1, len)fo(i, 1, len){if (a[i][k] < 0.00000000001) continue;fo(j, 1, len)c.a[i][j] += a[i][k] * b.a[k][j];}return c;}
}a, s, c;inline int read()
{int x = 0; char c = getchar();while (c < '0' || c > '9') c = getchar();while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();return x;
}inline int min(int x, int y) {return x < y ? x : y;}bool check(db p)
{mem(a.a, 0);a.a[len][len] = 1.0;fo(j, 0, R)fo(k, 1, Q){a.a[num[j][k]][len] = min(j + 1, R) * p;a.a[num[j][k]][num[min(j + 1, R)][min(k + 1, Q)]] = p;a.a[num[j][k]][num[0][k - 1]] = 1 - p;}
//  printf("%d\n", len);
//  fo(i, 1, len)
//  {
//      fo(j, 1, len)
//          printf("%.2lf ", a.a[i][j]);
//      puts("");
//  }int y = n;mem(s.a, 0);fo(i, 1, len) s.a[i][i] = 1;while (y){if (y & 1) s = s * a;a = a * a; y >>= 1;}return s.a[num[0][Q]][len] > S;
}int main()
{freopen("contra.in", "r", stdin);freopen("contra.out", "w", stdout);n = read(), R = read(), Q = read(), S = read();fo(j, 0, R)fo(k, min(j + 1, Q), Q)num[j][k] = ++len;++len;if (! check(1.0)) {printf("Impossible."); return 0;}while (l + 0.000000001 < r){mid = (l + r) / 2.0;if (check(mid)) r = mid;else l = mid;}printf("%.6lf", r);return 0;
}

转载于:https://www.cnblogs.com/jz929/p/11291416.html

jzoj 2867. 【集训队互测 2012】Contra相关推荐

  1. 洛谷 P4463 [集训队互测 2012] calc(拉格朗日插值优化DP)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Weblink https://www.luogu.com.cn/problem/P4463 Prob ...

  2. UOJ#191. 【集训队互测2016】Unknown

    UOJ#191. [集训队互测2016]Unknown 题目描述 Solution 二进制分组. 每一个组内维护一个斜率单调减的凸包. 因为有删点,避免出现反复横跳产生的爆炸复杂度,需要等到同一深度的 ...

  3. [2015国家集训队互测]口胡

    比赛链接 http://uoj.ac/contest/11 口胡题解 A.[集训队互测2015]Robot 直接果断打暴力了...这个暴力很好写,我就不废话了 B.[集训队互测2015]Marketi ...

  4. 「2019 集训队互测 Day 1」最短路径 解题报告

    一.题目概述 题目链接:Libre OJ. 给出一张图,求出 ans=∑i=1n∑j=1n[i≠j]dk(i,j)ans=\sum_{i=1}^n\sum_{j=1}^n[i\ne j]\texttt ...

  5. 【LOJ3077】「2019 集训队互测 Day 4」绝目编诗

    [题目链接] 点击打开链接 [思路要点] 不难发现各个边双连通分量可以分开处理,桥边可以直接删除. 可以证明,对于每一个边双连通分量,当 M−NM-NM−N 超过 O(N)O(\sqrt{N})O(N ...

  6. 【集训队互测2015】最大异或和

    首先不知道有没有神仙线段树分治过的. 首先一个较为显然的性质: \[ \mathrm{Span}\{v_1, v_2, \dots, v_n\} = \mathrm{Span}\{v_1, v_2 - ...

  7. 【uoj#94】【集训队互测2015】胡策的统计(集合幂级数)

    题目传送门:http://uoj.ac/problem/94 这是一道集合幂级数的入门题目.我们先考虑求出每个点集的连通生成子图个数,记为$g_S$,再记$h_S$为点集$S$的生成子图个数,容易发现 ...

  8. Loj#3077-「2019 集训队互测 Day 4」绝目编诗【结论,虚树,鸽笼原理】

    正题 题目链接:https://loj.ac/p/3077 题目大意 给出nnn个点mmm条边的一张简单无向图,求是否存在两个长度相等的简单环. 1≤n≤104,1≤m≤1061\leq n\leq ...

  9. jzoj2908,P1527-[集训队互测 2012]矩阵乘法【整体二分,二维树状数组】

    正题 题目链接:https://www.luogu.org/problem/P1527 题目大意 给出一个矩阵,每个询问求子矩阵中的第kkk小数. 解题思路 我们发现我们对于每个询问我们可以二分答案, ...

最新文章

  1. linux搭建directx环境,微軟開始在WSL 2環境中的Linux支援DirectX
  2. P1216 [IOI1994][USACO1.5]数字三角形 Number Triangles(简单dp)
  3. SWOT分析是神马?
  4. [转] css3变形属性transform
  5. Boost Graph
  6. python遇到异常跳过_教你使用Python遇到的异常的处理方式!
  7. 将数据库表中的数据读出以xml的形式下载到手机端
  8. Android技术总监应该干的哪些事
  9. Berkeley CS 61B 学习笔记 - 1
  10. 总结js实现字符串转JSON对象的几种方法
  11. icem二维非结构网格划分_Ansys Icem CFD网格划分实例详解PDF及附件
  12. ImportError: DLL load failed while importing win32file
  13. 【学术相关】过来人对研究生阶段的学习建议
  14. CTF密码学解题思路
  15. 一步完成最小二乘法、递推最小二乘法、增广最小二乘法、广义最小二乘法、辅助变量法、二步法辨识(传递函数)
  16. ​历经 33 天,终于拿到了心仪的 Offer
  17. 交换机与路由器工作原理
  18. JAVA从网络下载文件到本地
  19. 游戏检测到计算机性能过低配色,重装系统后提示是否更改配色方案提高性能怎么办...
  20. sinx/x的极限为什么是1_在sinx/x中当x→0时极限为什么为1?

热门文章

  1. 彩色激光同轴位移计在点胶行业的应用(胶水测量)
  2. LabVIEW-IMAQ/IMAQdx/图像采集
  3. linux usb驱动样例,Linux 2.6字符设备驱动程序样例
  4. scala编程_Scala可以带回编程的喜悦吗?
  5. 使用canvas绘制一个动态的表盘
  6. HCIA 8-17 笔记
  7. Python 使用 matplotlib绘制3D图形
  8. 上海大学计算机学院 教授名录,教授名录
  9. 地产2022价值启示录:房企必须闯过的“三重门”
  10. ffmpeg简易使用应用分享(m3u8下载与视频合并等)