HDU4624Endless Spin(clj计数ppt)
2015-10-15 19:46
375 查看
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4624
题意:总共有n个球,每次随机选择一段区间染黑(每段区间被选择的概率相同),求期望多少次所有球都被染黑。
分析:虽然ppt中说显然,但我认为这个问题最为精妙的地方就在第一步:期望次数=∑i=1∞p[i]期望次数=\sum_{i=1}^\infty p[i],其中p[i]p[i]为i次之后仍然存在白球的概率。
这个公式怎么来的呢?直观的理解就是假如当前还有白球,那么必然还要染一次,而这一次对整体期望的贡献就是p[i].这之后就是传统的处理方法,枚举哪些球是白球,那么可以染黑的区间是固定的,由于这当中会有重复计算,只需要把奇数个白球的情况减去偶数个白球的方案数就是总的方案数,这种容斥方法在后面的Substring Pairs一题中也有体现。
另外,这题要保留15位小数,要用java才能通过。
java进行文件读写,可以使用Printwriter来做写操作,不过要记得close.
java可以方便的使用printf;
java的BigDecimal进行divide操作时,要设置scale和舍入mode
附上java代码
题意:总共有n个球,每次随机选择一段区间染黑(每段区间被选择的概率相同),求期望多少次所有球都被染黑。
分析:虽然ppt中说显然,但我认为这个问题最为精妙的地方就在第一步:期望次数=∑i=1∞p[i]期望次数=\sum_{i=1}^\infty p[i],其中p[i]p[i]为i次之后仍然存在白球的概率。
这个公式怎么来的呢?直观的理解就是假如当前还有白球,那么必然还要染一次,而这一次对整体期望的贡献就是p[i].这之后就是传统的处理方法,枚举哪些球是白球,那么可以染黑的区间是固定的,由于这当中会有重复计算,只需要把奇数个白球的情况减去偶数个白球的方案数就是总的方案数,这种容斥方法在后面的Substring Pairs一题中也有体现。
另外,这题要保留15位小数,要用java才能通过。
java进行文件读写,可以使用Printwriter来做写操作,不过要记得close.
java可以方便的使用printf;
java的BigDecimal进行divide操作时,要设置scale和舍入mode
附上java代码
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.math.BigDecimal; import java.math.BigInteger; import java.util.*; public class Main { public static void main(String[] args) throws FileNotFoundException { File fp2=new File("/home/poursoul/J.out"); PrintWriter cout=new PrintWriter(fp2); Long [][][]dp=new Long[55][2500][2]; BigDecimal []rep=new BigDecimal[100]; for(int i=0;i<60;i++)rep[i]=new BigDecimal("0"); for(int i=0;i<55;i++)for(int j=0;j<2500;j++)for(int k=0;k<2;k++)dp[i][j][k]=new Long(0); dp[0][0][0]=(long)1; BigDecimal t1=new BigDecimal("1"); for(int i=1;i<=51;i++) { for(int j=0;j<i*(i-1)/2;j++) { for(int k=0;k<2;k++) { for(int ni=0;ni<i;ni++) { int tot=i-ni-1; tot=tot*(tot+1)/2; if(j>=tot) dp[i][j][k]+=dp[ni][j-tot][k^1]; } } Long tp=(long)i*(i-1)/2; BigDecimal p=new BigDecimal(j).divide(new BigDecimal(tp.toString()), 50, BigDecimal.ROUND_HALF_UP); Long tp2=dp[i][j][1]-dp[i][j][0]; rep[i-1]=rep[i-1].add(t1.divide(t1.subtract(p), 50, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(tp2.toString()))); } dp[i][i*(i-1)/2][0]=new Long(1); } for(int n=1;n<=50;n++) cout.printf("\"%.15f\",\n",rep ); cout.close(); } }
相关文章推荐
- 直接对Object数组进行赋值
- 静态构造函数
- 记录git中的一些命令
- PHP 拼接HTTP请求字符串
- ora-01654pk_sceautosm无法通过8(在表空间servicxe_main_idx扩展)
- ACdream运动会(送)
- 重联通分量(Tarjan+模拟栈)
- POJ1681 Painter's Problem 高斯消元+枚举
- 宏观经济分析
- Python time time()方法返回的是秒
- apache-hive-1.2.1 安装与MYSQL配置
- UVa.1587
- OS10.11系统下 安装cocoapods 以及 安装cocoapods-xcode-plugin-master插件来加载三方框架
- Nginx 配置 SSL 及 SSL 证书的创建过程
- Codevs3269 混合背包
- 怎样理解阻塞非阻塞与同步异步的区别
- Web应用中并发控制的实现
- OC ---封装与方法
- 单链表简单操作1
- Unity响应Android的返回键,退出当前Activity