概率DP
这就是一个乱搞题,暴力发现TLE了,然后看了看discuss里说可以矩阵加速,想了一会才想明白怎么用矩阵,分着算的啊。先算f[num[i]-1]之类的,代码太长了,还是找找规律吧。。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
using namespace std;
#define eps 1e-8
int num[];
int judge(double x,double y)
{
double t = x-y;
if(t < )
t = -t;
if(t < eps)
return ;
else
return ;
}
int main()
{
int i,j,n,maxz;
double p,f1,f2;
while(scanf("%d%lf",&n,&p)!=EOF)
{
maxz = ;
for(i = ; i < n; i ++)
{
scanf("%d",&num[i]);
maxz = max(num[i],maxz);
}
sort(num,num+n);
if(num[] == )
{
printf("0.0000000\n");
}
else
{
f2 = ;
f1 = ;
for(i = ; i <= maxz+; i ++)
{
double t;
for(j = ;j < n;j ++)
{
if(num[j] == i)
break;
}
if(j != n)
{
swap(f2,f1);
f2 = ;
}
else
{
t = f2;
f2 = f2*p + f1*(-p);
f1 = t;
}
if(judge(f1,f2))
{
for(j = ;j < n;j ++)
{
if(num[j] > i)
{
i = num[j]-;
break;
}
}
}
}
printf("%.7lf\n",f2);
}
}
return ;
}
乱推推,题意看清楚。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <algorithm>
#include <vector>
using namespace std;
#define eps 1e-8
double dp[][];
int in[][];
double dfs(int w,int b)
{
double t;
if(in[w][b])
return dp[w][b];
if(w == )
return ;
t = w*1.0/(w+b);
in[w][b] = ;
if(b >= )
{
if(b- > )
return dp[w][b] = t + b*1.0/(w+b)*(b-)/(w+b-)*(b-)/(w+b-)*dfs(w,b-) + b*1.0/(w+b)*(b-)/(w+b-)*w/(w+b-)*dfs(w-,b-);
else
return dp[w][b] = t + b*1.0/(w+b)*(b-)/(w+b-)*w/(w+b-)*dfs(w-,b-);
}
return dp[w][b] = t;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
printf("%.9lf\n",dfs(n,m));
return ;
}
入门题。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
using namespace std;
#define eps 1e-6
double dp[][];
double w[][][];
int judge(double x)
{
if(x < )
x = -x;
if(x < eps)
return ;
else
return ;
}
int main()
{
int m,n,i,j,k;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i = ;i < n;i ++)
{
for(j = ;j < m;j ++)
{
for(k = ;k < ;k ++)
scanf("%lf",&w[i][j][k]);
}
}
dp[n-][m-] = ;
for(i = n-;i >= ;i --)
{
for(j = m-;j >= ;j --)
{
if(i == n-&&j == m-) continue;
if(judge(w[i][j][]-)) continue;
dp[i][j] = (dp[i][j+]*w[i][j][] + dp[i+][j]*w[i][j][] + )/(-w[i][j][]);
}
}
printf("%.3lf\n",dp[][]);
}
return ;
}
硬做就行,取整符号,你认识吗...
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
#define eps 1e-8
double dp[];
int in[];
int c[];
int n;
double dfs(int x)
{
int i;
if(in[x])
return dp[x];
double ans,t2;
t2 = ((sqrt(5.0)+))*0.5;
ans = ;
for(i = ;i < n;i ++)
{
if(x > c[i])
ans += (int)(t2*c[i]*c[i]);
else
ans += dfs(x+c[i])+;
}
ans /= n;
in[x] = ;
return dp[x] = ans;
}
int main()
{
int i,f;
while(scanf("%d%d",&n,&f)!=EOF)
{
memset(in,,sizeof(in));
for(i = ;i < n;i ++)
scanf("%d",&c[i]);
printf("%.3lf\n",dfs(f));
}
return ;
}
ZOJ 3380 Patchouli's Spell Cards
这个题,完全就是组合DP的感觉。
题意要求至少有l个,求反面,所有的数字都是0-l-1就行了。
dp[i][j] 前j种,放了i个位置,枚举当前颜色,放0到l-1种,这个问题就是m个位置,插入n个相同的数,以前做过,把n插板,然后从m+1个空里选。
用java第一次TLE了,记忆化了一下fun函数,就过了。
import java.math.BigInteger;
import java.util.Scanner; public class Main {
static BigInteger c[][] = new BigInteger[101][101];
static BigInteger s[][] = new BigInteger[110][110];
static boolean in[][] = new boolean[110][110];
public static BigInteger gcd(BigInteger a, BigInteger b) {
if (b.compareTo(BigInteger.valueOf(0)) == 0)
return a;
else
return gcd(b, a.mod(b));
} public static BigInteger fun(int n, int m) {
int minz, i;
if(in[n][m])
return s[n][m];
if (n == 0 || m == 0)
return BigInteger.valueOf(1);
if (n < m + 1)
minz = n;
else
minz = m + 1;
BigInteger ans = BigInteger.valueOf(0);
for (i = 1; i <= minz; i++) {
ans = ans.add(c[m + 1][i].multiply(c[n - 1][i - 1]));
}
in[n][m] = true;
return s[n][m] = ans;
} public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
BigInteger dp[][] = new BigInteger[101][101];
int i, j, k, n, m, l;
for (i = 0; i <= 100; i++) {
for (j = 0; j <= 100; j++)
c[i][j] = BigInteger.valueOf(0);
}
for (i = 0; i <= 100; i++)
c[i][0] = BigInteger.valueOf(1); for (i = 1; i <= 100; i++) {
for (j = 1; j <= 100; j++)
c[i][j] = c[i - 1][j - 1].add(c[i - 1][j]);
}
while (cin.hasNext()) {
m = cin.nextInt();
n = cin.nextInt();
l = cin.nextInt();
if (l > m) {
System.out.println("mukyu~");
continue;
}
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++)
dp[i][j] = BigInteger.valueOf(0);
}
dp[0][0] = BigInteger.valueOf(1);
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
for (k = 0; k < l; k++) {
if (dp[i][j].compareTo(BigInteger.valueOf(0)) == 0)
continue;
if (i + k > m)
continue;
dp[i + k][j + 1] = dp[i + k][j + 1].add(dp[i][j]
.multiply(fun(i, k)));
}
}
}
BigInteger ans = BigInteger.valueOf(n).pow(m);
BigInteger res = BigInteger.valueOf(0);
for (i = 1; i <= n; i++) {
res = res.add(dp[m][i]);
}
BigInteger t = gcd(ans.subtract(res), ans);
System.out.println(ans.subtract(res).divide(t) + "/"
+ ans.divide(t));
} }
}
感觉是神题呢,这是咋推的,我想了半天,硬做来了个二维的...看别人的题解,直接一位搞定。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
int n,num;
double dp[];
double dfs(int step,int m)
{ double ans;
if(step == n)
{
return (m*1.0/num);
}
ans = (m*1.0/num)*(dfs(step+,m-) + );
if(m != num)
ans += (num-m)*1.0/num*dfs(step+,m);
return ans;
}
int main()
{
int m,i;
// while(scanf("%d%d",&m,&n)!=EOF)
// {
// num = m;
// printf("%.9lf\n",dfs(1,m));
// }
while(scanf("%d%d",&n,&m)!=EOF)
{
dp[] = ;
for(i = ;i <= m;i ++)
dp[i] = (-dp[i-])*dp[i-] + dp[i-]*(dp[i-]-1.0/n);
double ans = ;
for(i = ;i <= m;i ++)
ans += dp[i];
printf("%.10lf\n",ans);
}
return ;
}
跟省赛的题非常相似,所有的dp[i]都用o1[i]*dp[0]+o2[i]表示,最后就解出dp[0]来了。
#include <cstdio>
using namespace std;
double o1[];
double o2[];
int main()
{
int n,k1,k2,k3,a,b,c,i,j,k,u,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d%d%d%d",&n,&k1,&k2,&k3,&a,&b,&c);
for(i = n;i >= ;i --)
{
o1[i] = 1.0/k1/k2/k3;
o2[i] = ;
for(j = ;j <= k1;j ++)
{
for(k = ;k <= k2;k ++)
{
for(u = ;u <= k3;u ++)
{
if(i+j+k+u > n) continue;
if(j == a&&k == b&&u == c) continue;
o1[i] += 1.0/k1/k2/k3*o1[i+j+k+u];
o2[i] += 1.0/k1/k2/k3*o2[i+j+k+u];
}
}
}
}
printf("%.10lf\n",o2[]/(1.0-o1[]));
}
return ;
}
概率DP的更多相关文章
- Codeforces 28C [概率DP]
/* 大连热身D题 题意: 有n个人,m个浴室每个浴室有ai个喷头,每个人等概率得选择一个浴室. 每个浴室的人都在喷头前边排队,而且每个浴室内保证大家都尽可能均匀得在喷头后边排队. 求所有浴室中最长队 ...
- HDU 4405 Aeroplane chess (概率DP)
题意:你从0开始,要跳到 n 这个位置,如果当前位置是一个飞行点,那么可以跳过去,要不然就只能掷骰子,问你要掷的次数数学期望,到达或者超过n. 析:概率DP,dp[i] 表示从 i 这个位置到达 n ...
- POJ 2096 Collecting Bugs (概率DP)
题意:给定 n 类bug,和 s 个子系统,每天可以找出一个bug,求找出 n 类型的bug,并且 s 个都至少有一个的期望是多少. 析:应该是一个很简单的概率DP,dp[i][j] 表示已经从 j ...
- POJ 2151 Check the difficulty of problems (概率DP)
题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 ,求每队至少解出一题且冠军队至少解出N道题的概率. 析:概率DP,dp[i][j][k] 表示第 i 个队伍,前 j 个题,解出 ...
- 概率DP light oj 1030
t组数据 n块黄金 到这里就捡起来 出发点1 到n结束 点+位置>n 重掷一次 dp[i] 代表到这里的概率 dp[i]=(dp[i-1]+dp[i-2]... )/6 如果满6个的话 否则 ...
- hdu 4050 2011北京赛区网络赛K 概率dp ***
题目:给出1-n连续的方格,从0开始,每一个格子有4个状态,左右脚交替,向右跳,而且每一步的步长必须在给定的区间之内.当跳出n个格子或者没有格子可以跳的时候就结束了,求出游戏的期望步数 0:表示不能到 ...
- [转]概率DP总结 by kuangbin
概率类题目一直比较弱,准备把kuangbin大师傅总结的这篇题刷一下! 我把下面的代码换成了自己的代码! 原文地址:http://www.cnblogs.com/kuangbin/archive/20 ...
- SGU 422 Fast Typing(概率DP)
题目大意 某人在打字机上打一个字符串,给出了他打每个字符出错的概率 q[i]. 打一个字符需要单位1的时间,删除一个字符也需要单位1的时间.在任意时刻,他可以花 t 的时间检查整个打出来的字符串,并且 ...
- HDU 4050 wolf5x(动态规划-概率DP)
wolf5x Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- 概率dp入门
概率DP主要用于求解期望.概率等题目. 转移方程有时候比较灵活. 一般求概率是正推,求期望是逆推.通过题目可以体会到这点. poj2096:Collecting Bugs #include <i ...
随机推荐
- 简述block
block传值也适用于从后往前传值 先介绍block的基本知识 /** * 1.如何定义一个Block变量 2.怎样给定义的Block变量赋初值 3.如何冲定义Block类型 4.如何使用Block实 ...
- [NHibernate]NHibernate.Tool.hbm2net
系列文章 [Nhibernate]体系结构 [NHibernate]ISessionFactory配置 [NHibernate]持久化类(Persistent Classes) [NHibernate ...
- 【html】学习记录-拖放(drag and drop)
目的:实现拖动目标并放置到指定区域. 使元素可拖动,涉及到元素的全局属性draggable <img draggable="true" /> 即img元素设置为可拖 ...
- $_SERVER["SCRIPT_NAME"]、$_SERVER["PHP_SELF"]、$_SERVER["QUERY_STRING"]、$_SERVER["REQUEST_URI"]
1.$_SERVER["SCRIPT_NAME"] 说明:包含当前脚本的路径 2.$_SERVER["PHP_SELF"] 说明:当前正在执行脚本的文件名 3. ...
- 2.MongoDB 基于node.js访问和操作集合
对于频繁使用的Node.js来说,常见的任务是集合的动态操控. 较大的安装给每个大客户一个单独的集合,以便客户登入或离开时.根据需要添加或删除集合. MongoDB Node.js 驱动程序 Db和C ...
- Sublime Text3中Autoprefixer失效解决方法
进入CSS文件,默认配置在按下快捷键(Ctrl+Shift+P)后输入Autoprefix,你会发觉它什么事也没干,然后--这什么鬼?抓狂ing-- 原来是因为这玩意还要配置下,以下为配置方法: Pr ...
- 上个项目的一些反思 I
最近一直在反思之前的项目,发现了很多问题.比如数据安全... 虽然项目需求是只展示最新的数据,所以几乎没用什么本地存储.除了通讯录和用户的Token. 用户通讯录另表,今天反思下用户的Token的存储 ...
- VIM插件攻略
工欲善其事,必先利其器.一个强大的开发环境可以大大提高工作效率.好吧,我知道这是废话...不过,我想一定有很多跟我一样打算进入Linux平台开发的新手,一开始都为找不到一个像Windows下的VS那样 ...
- c语言libcurl库的异步用法
multi接口的使用会比easy 接口稍微复杂点,毕竟multi接口是依赖easy接口的,首先粗略的讲下其使用流程:curl_multi _init初始化一个multi curl对象,为了同时进行多个 ...
- MyBatis的初始化方式
1. 加载配置文件 public static void main(String[] args) throws IOException { //mybatis的配置文件 String resource ...