BZOJ 4204 取球游戏 循环矩阵优化期望递推
2015-08-06 16:53
369 查看
题意:链接
方法:循环矩阵优化期望递推。
解析:
这题递推没啥,主要是循环矩阵优化
我们发现,如果直接上矩阵优化的话是n^3log,所以铁定是过不了了的,然后再观察一下这道题我们要求幂的矩阵,发现他是这种形式
1 1 0 0 0
0 1 1 0 0
0 0 1 1 0
0 0 0 1 1
1 0 0 0 1
每一行都是上一行向右窜了一位
所以我们可以用一个一维数组代表这个循环矩阵
并且循环矩阵求和,乘积还是循环矩阵
所以我们就可以用循环矩阵来优化掉一个n
复杂度即变为了n^2log 可过。
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 1010 using namespace std; int n,m,k; int a ; struct Matrix { double map ; }; Matrix ori; Matrix bas; Matrix bask; Matrix ans; Matrix c; // f[i][j]表示第i次拿出标号为j的球的期望 // f[i][j]=f[i-1][j]+1/m*f[i-1][j-1]-1/m*f[i-1][j]; Matrix mul(Matrix a,Matrix b) { for(int i=1;i<=n;i++) { c.map[i]=0; for(int j=1;j<=n;j++) { c.map[i]+=a.map[j]*b.map[(i-j+n+1)%n==0?n:(i-j+n+1)%n]; } } return c; } Matrix quick_my(Matrix a,int y) { Matrix ret; memset(ret.map,0,sizeof(ret.map)); ret.map[1]=1; while(y) { if(y&1) { ret=mul(ret,a); } a=mul(a,a); y>>=1; } return ret; } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=n;i++)ori.map[i]=(double)a[i]; bas.map[1]=(double)(m-1)/(double)m; bas.map[2]=1.0/(double)m; bask=quick_my(bas,k); ans=mul(ori,bask); for(int i=1;i<=n;i++)printf("%.3lf\n",ans.map[i]); }
相关文章推荐
- PHP文件上传
- Android Studio之同一窗口打开项目
- cookie类的简单创建
- thinkphp模块
- hibernate3下载地址
- thinkphp连接数据库
- 单位冲击响应与频响以及FIR实现代码(C语言)(转)
- android解决部分手机无法通过uri获取到相册的path
- bzoj3576: [Hnoi2014]江南乐
- nodejs环境搭建(linux版)
- scrollview的无缝循环滚动
- hive优化二
- Objective-C特性:Runtime
- 内存溢出 MAT jvisualVM
- Android开发常用系统权限
- Android进程间通信之LocalSocket通信
- Ubuntu 安装 Maven/Nexus
- Eclipse配置Tomcat和JDK步骤图解
- SQL Server数据迁移到MySQL
- JPA环境搭建