二分概率+矩乘+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的更多相关文章

  1. bzoj2676 Contra

    题意: 给定N,R,Q,S 有N个关卡,初始有Q条命,且任意时刻最多只能有Q条命 每通过一个关卡,会得到u分和1条命,其中u=min(最近一次连续通过的关数,R) 若没有通过这个关卡,将失去一条命,并 ...

随机推荐

  1. 4.JAVA语言基础部分—枚举与泛型

    枚举 //定义枚举 enum MyEnum{ ITEM_A, ITEM_B } public static void main(String[] args) { //values()获取所枚举项的集合 ...

  2. 用systemtap来做系统性能分析和事件分析

    http://zhengheng.me/2015/02/11/systemtap-analy/

  3. JDK动态代理理解精髓

      1.Java动态代理的关键是:Proxy类要和InvocationHandler的接口实现类,要用同一个目标target对象class,所以精髓是InvocationHandler和Proxy是一 ...

  4. scp操作实例

    scp 可用于文件的上传与下载,默认端口号是22,通常我们为了安全起见会将默认端口号修改了,而不去直接使用默认的22端口,以下我们以8888端口为例 目标机器 A :192.168.10.30 目标机 ...

  5. PythonCookbook读书笔记

    第一章 数据结构和算法 1.1 将序列分解为单独的变量 适用于元组.列表.字符串等.只要是可迭代的对象,都可以执行分解操作.唯一的要求是变量的总数和结构要与序列相同. 1.2 从任意长度的可迭代对象中 ...

  6. malloc动态分配多维数组

    下面试自己写的三个测试程序,如果看懂了基本上动态分配多维数组就没什么问题啦:重点 1:深刻理解多维数组的概念,多维数组在内存中的分配情况,基本上动态分配也没什么问题的.然后还要注意一点的就是,释放是分 ...

  7. 在Nginx上部署ThinkPHP,解决Pathinfo问题

    在Nginx上部署ThinkPHP,解决Pathinfo问题 事实上.要解决nginx不支持pathinfo的问题.有两个解决思路,一是不使用pathinfo模式,二是改动nginx的配置文件,使它支 ...

  8. C#如何设置控件水平对齐,垂直对齐

    如果要设置一些控件垂直对齐,点击这个按钮 如果要设置水平对齐,则点击这个按钮,选中控件之后点击左对齐(多个按钮都试下吧,总归能对齐到你要的效果的)

  9. 零售连锁行业SOA化解决方式

    零售连锁行业面临的问题 1.店铺老化.营销手段单一落后. 2.管理模式的不科学,我国零售企业在起家时候并没有一套完好的科学的管理及考评系统的存在.而且在企业的发展过程中并未学习建立.对于人才的吸引.培 ...

  10. java开始到熟悉63-65

    本次内容:java常用类 1.包装类 package array; public class wrapperclass { public static void main(String[] args) ...