bzoj2676
二分概率+矩乘+dp
也是二分概率,然后dp[i][j][k]表示当前到了i,有j条命,下一次的收益是k,然后矩乘转移,但是我自己的似乎wa了,抄了liu_runda的才行,具体不知道为什么
注释的是我自己写的,谁能告诉我哪里错了?
- #include<bits/stdc++.h>
- using namespace std;
- const int N = ;
- int n, r, q, tot;
- int id[N][N];
- double S;
- struct matrix {
- double a[N][N];
- matrix() { for(int i = ; i <= tot; ++i) for(int j = ; j <= tot; ++j) a[i][j] = 0.0; }
- matrix friend operator * (const matrix &a, const matrix &b) {
- matrix ret;
- for(int k = ; k <= tot; ++k)
- for(int i = ; i <= tot; ++i) if(a.a[i][k] >= 1e-)
- for(int j = ; j <= tot; ++j)
- ret.a[i][j] += a.a[i][k] * b.a[k][j];
- return ret;
- }
- void set() {
- for(int i = ; i <= tot; ++i) a[i][i] = 1.0;
- }
- };
- double calc(double p)
- {
- matrix A, B;
- A.set();
- /*
- 第i轮j条命这一次得k分
- dp[i][j][k]=(dp[i+1][j + 1][k + 1] + k) * p
- dp[i][j][k] += dp[i + 1][j - 1][1] * (1.0 - p)
- 矩阵乘法
- */
- B.a[tot][tot] = 1.0;
- for(int i = ; i <= q; ++i)
- for(int j = ; j <= r; ++j)
- {
- if(i > ) B.a[id[i - ][]][id[i][j]] = 1.0 - p;
- B.a[tot][id[i][j]] = p * (double)j;
- if(i < q && j < r) B.a[id[i + ][j + ]][id[i][j]] = p;
- else if(i < q) B.a[id[i + ][j]][id[i][j]] = p;
- else if(j < r) B.a[id[i][j + ]][id[i][j]] = p;
- else B.a[id[i][j]][id[i][j]] = p;
- }
- // for(int j = 0; j <= q; ++j)
- // for(int k = 1; k <= r; ++k) B.a[tot][id[j][k]] = p * (double)k;
- // for(int j = 0; j <= q; ++j)
- // for(int k = 1; k <= r; ++k) B.a[id[min(j + 1, q)][min(k + 1, r)]][id[j][k]] = p;
- // for(int j = 2; j <= q; ++j)
- // for(int k = 1; k <= r; ++k) B.a[id[j - 1][1]][id[j][k]] = 1.0 - p;
- for(int i = n; i; i >>= , B = B * B) if(i & ) A = A * B;
- // double ret = 0.0;
- // for(int i = 0; i <= tot; ++i)
- // {
- // for(int j = 0; j <= tot; ++j) printf("%.6f ", A.a[i][j]);
- // puts("");
- // }
- // for(int i = 0; i < tot; ++i) ret += A.a[tot][i];
- // printf("p = %.6f ret = %.6f\n", p, ret);
- return A.a[tot][id[q][]];
- }
- int main()
- {
- scanf("%d%d%d%lf", &n, &r, &q, &S);
- for(int i = ; i <= q; ++i)
- for(int j = ; j <= r; ++j) id[i][j] = tot++;
- // printf("tot = %d\n", tot);
- double l = 0.0, r = 1.0, ans = -1.0;
- while(r - l > 1e-)
- {
- double mid = (l + r) / 2.0;
- if(calc(mid) > S) r = ans = mid;
- else l = mid;
- }
- if(ans == -1.0) puts("Impossible.");
- else printf("%.6f\n", ans);
- return ;
- }
bzoj2676的更多相关文章
- bzoj2676 Contra
题意: 给定N,R,Q,S 有N个关卡,初始有Q条命,且任意时刻最多只能有Q条命 每通过一个关卡,会得到u分和1条命,其中u=min(最近一次连续通过的关数,R) 若没有通过这个关卡,将失去一条命,并 ...
随机推荐
- Kafka windows下的安装
1. 安装JDK 1.1 安装文件:http://www.oracle.com/technetwork/java/javase/downloads/index.html 下载JDK1.2 安装完成后需 ...
- LSTM网络
http://colah.github.io/posts/2015-08-Understanding-LSTMs/ https://www.jianshu.com/p/9dc9f41f0b29 机器学 ...
- DOS环境进入及基本命令
DOS:磁盘操作系统(Disk Operating System) Window环境下如何进入DOS: 1. 以win10为例,按ctrl+R打开运行窗口,在输入框输入"CMD"并 ...
- 转: 在CentOS 6.X 上面安装 Python 2.7.X
转:https://ruiaylin.github.io/2014/12/12/python%20update/ 评注: yum -y update //这个更新太坑了,1120更新包...想死的心都 ...
- linux cat 文件操作
简略版: cat主要有三大功能:1.一次显示整个文件.$ cat filename2.从键盘创建一个文件.$ cat > filename 只能创建新文件,不能编辑已有文件.3.将几个文 ...
- 嵌入式开发之davinci--- 8148/8168/8127 中的添加算饭scd 场景检测 代码实现
http://blog.csdn.net/mianhuantang848989/article/details/38035731 http://www.61ic.com/Article/DaVinci ...
- Android 打造随意层级树形控件 考验你的数据结构和设计
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40212367,本文出自:[张鸿洋的博客] 1.概述 大家在项目中或多或少的可能会 ...
- Android — 长按ListView 利用上下文菜单(ActionMode) 进行批量事件处理
好久没写博客拉``````` 近期最终略微闲一点了``````` 无聊拿手机清理短信.发现批量事件的处理还是挺管用的`````` 那么自己也来山寨一记看看效果吧````` 闲话少说,首先,我们来看下手 ...
- Vue 之 npm 及 安装的包
1 npm相关 1.1 npm 是 基于Node.js 的,所以要先安装Node.js 在浏览器地址栏输入https://nodejs.org/en/, 进入Node.js官网后,点击下载左边的稳定 ...
- LiberOJ#6178. 「美团 CodeM 初赛 Round B」景区路线规划 概率DP
题意 游乐园被描述成一张 n 个点,m 条边的无向图(无重边,无自环).每个点代表一个娱乐项目,第 i 个娱乐项目需要耗费 ci 分钟的时间,会让小 y 和妹子的开心度分别增加 h1i ,h2i ,他 ...