poj 2096

题目:http://poj.org/problem?id=2096

f[ i ][ j ] 表示收集了 i 个 n 的那个、 j 个 s 的那个的期望步数。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define db double
using namespace std;
const int N=;
db n,s,f[N][N];
int main()
{
scanf("%lf%lf",&n,&s);db ml=n*s;
for(int i=n;i>=;i--)
for(int j=s;j>=;j--)
{
if(i==n&&j==s)continue;
if(i<n)f[i][j]+=(n-i)*j/ml*f[i+][j];
if(j<s)f[i][j]+=i*(s-j)/ml*f[i][j+];
if(i<n&&j<s)f[i][j]+=(n-i)*(s-j)/ml*f[i+][j+];
f[i][j]+=;
f[i][j]*=ml/(ml-i*j);
}
printf("%.4f\n",f[][]);
return ;
}

ZOJ 3329

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3754

高斯消元好像时间复杂度太高。

注意到每个位置都可以从 dp[ 0 ] 转移过来,所以可以想到每个 dp[ i ] 都可以表示成 a[ i ]*dp[ 0 ] + b[ i ] 的形式;这样如果算出了 a[ 0 ] 和 b[ 0 ] ,就能直接算出 dp[ 0 ] 了。

\( dp[i]=a[i]*dp[0]+b[i] \)

\( dp[i]=\sum\limits_{j=1}^{k}dp[i+j]*p[j] + dp[0]*p[0] + 1 \)

\( dp[i]=\sum\limits_{j=1}^{k}(a[i+j]*p[j]*dp[0]+b[i+j]*p[j]) + dp[0]*p[0] + 1 \)

\( dp[i]=((\sum\limits_{j=1}^{k}a[i+j]*p[j])+p[0])dp[0]+(\sum\limits_{j=1}^{k}b[i][j]*p[j])+1 \)

所以 \( a[i]=(\sum\limits_{j=1}^{k}a[i+j]*p[j])+p[0] \) , \( b[i]=(\sum\limits_{j=1}^{k}b[i][j]*p[j])+1 \)

注意多组数据的清零。空间不是 505 而是 525 。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define db double
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
const int N=,M=;
int n,c[],t[]; db p[M],a[N],b[N];
int main()
{
int T=rdn();
while(T--)
{
n=rdn();for(int i=;i<=;i++)c[i]=rdn();
for(int i=;i<=;i++)t[i]=rdn();
db tp=1.0/(c[]*c[]*c[]); p[]=tp;
int lm=c[]+c[]+c[];
for(int i=;i<=lm;i++)p[i]=;//
for(int i=;i<=c[];i++)
for(int j=;j<=c[];j++)
for(int k=;k<=c[];k++)
{
if(i==t[]&&j==t[]&&k==t[])continue;
p[i+j+k]+=tp;
}
for(int i=;i<=n;i++)a[i]=p[],b[i]=;
for(int i=n+,j=n+lm;i<=j;i++)a[i]=b[i]=;////
for(int i=n;i>=;i--)
for(int j=;j<=lm;j++)
a[i]+=a[i+j]*p[j],b[i]+=b[i+j]*p[j];
printf("%.10f\n",b[]/(-a[]));
}
return ;
}

hdu 4035

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4035

设 f[ i ] 表示现在在 i 号点,期望走几步离开迷宫。

数据范围无法高斯消元。

考虑把 f[ i ] 表示成 a[ i ] * f[ 1 ] + b[ i ] 的形式,这样才能在知道系数之后算出 f[ 1 ] 。它是从 1 号点开始走的,所以应该能表示成这样。

只是这样的话,转移还是没有顺序的。所以考虑把 f[ i ] 表示成 a[ i ] * f[ 1 ] + b[ i ] * f[ fa ] + c[ i ] 的形式。

\( f[i] = k[i]*f[1]+e[i]*0 + \frac{1-k[i]-e[i]}{d[i]}(f[fa]+1) + \frac{1-k[i]-e[i]}{d[i]}\sum\limits_{j \in child}(f[j]+1) \)

\( f[i] = a[i]*f[1]+b[i]*f[fa]+c[i] \)   令 \( s[i]=\frac{1-k[i]-e[i]}{d[i]} \)

\( f[i]=k[i]*f[1]+s[i]*f[fa]+s[i]+(d[i]-1])s[i]+s[i]\sum\limits_{j \in child}(a[j]*f[1]+b[j]*f[i]+c[j]) \)

\( f[i]=k[i]*f[1]+s[i]*f[fa]+d[i]*s[i]+s[i]\sum\limits_{j \in child}a[j]*f[1]+s[i]\sum\limits_{j \in child}b[j]*f[i]+s[i]\sum\limits_{j \in child}c[j] \)

\( (1-s[i]\sum\limits_{j \in child}f[i]=(k[i]+s[i]\sum\limits_{j \in child}a[j])f[1]+s[i]*f[fa]+d[i]*s[i]+s[i]\sum\limits_{j \in child}c[j] \)

答案就是 \( \frac{c[1]}{1-a[1]} \) 。当 \( 1 = a[1] \) 时无解。

精度开成 1e-8 会 WA , 1e-9 就可以了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define db double
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
const int N=1e4+;const db eps=1e-;
int n,hd[N],xnt,to[N<<],nxt[N<<],d[N];db k[N],e[N],s[N],a[N],b[N],c[N];
void add(int x,int y){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;d[x]++;}
void dfs(int cr,int fa)
{
db tp=;
for(int i=hd[cr],v;i;i=nxt[i])
if((v=to[i])!=fa)
{
dfs(v,cr);a[cr]+=a[v];c[cr]+=c[v];tp+=b[v];
}
a[cr]=a[cr]*s[cr]+k[cr]; b[cr]=s[cr]; c[cr]=c[cr]*s[cr]+d[cr]*s[cr];
tp=-tp*s[cr];
a[cr]/=tp; b[cr]/=tp; c[cr]/=tp;
}
int main()
{
int T=rdn();
for(int t=;t<=T;t++)
{
n=rdn();memset(hd,,sizeof hd);xnt=;
for(int i=;i<=n;i++)d[i]=;
for(int i=,u,v;i<n;i++)
u=rdn(),v=rdn(),add(u,v),add(v,u);
for(int i=;i<=n;i++)
{
k[i]=(db)rdn()/;e[i]=(db)rdn()/;
s[i]=(-k[i]-e[i])/d[i];
a[i]=b[i]=c[i]=;
}
dfs(,); printf("Case %d: ",t);
if(fabs(-a[])<=eps)puts("impossible");
else printf("%.10f\n",c[]/(-a[]));
}
return ;
}

poj 2096 Collecting Bugs && ZOJ 3329 One Person Game && hdu 4035 Maze——期望DP的更多相关文章

  1. POJ 2096 Collecting Bugs 期望dp

    题目链接: http://poj.org/problem?id=2096 Collecting Bugs Time Limit: 10000MSMemory Limit: 64000K 问题描述 Iv ...

  2. POJ 2096 Collecting Bugs (概率DP,求期望)

    Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material stu ...

  3. POJ 2096 Collecting Bugs

    Collecting Bugs Time Limit: 10000MS   Memory Limit: 64000K Total Submissions: 1716   Accepted: 783 C ...

  4. poj 2096 Collecting Bugs(期望 dp 概率 推导 分类讨论)

    Description Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other ...

  5. poj 2096 Collecting Bugs 概率dp 入门经典 难度:1

    Collecting Bugs Time Limit: 10000MS   Memory Limit: 64000K Total Submissions: 2745   Accepted: 1345 ...

  6. Poj 2096 Collecting Bugs (概率DP求期望)

    C - Collecting Bugs Time Limit:10000MS     Memory Limit:64000KB     64bit IO Format:%I64d & %I64 ...

  7. poj 2096 Collecting Bugs 【概率DP】【逆向递推求期望】

    Collecting Bugs Time Limit: 10000MS   Memory Limit: 64000K Total Submissions: 3523   Accepted: 1740 ...

  8. POJ 2096 Collecting Bugs:期望dp

    题目链接:http://poj.org/problem?id=2096 题意: 有一个程序猿,他每天都会发现一个bug. bug共有n个种类.属于某一个种类的概率为1/n. 有s个子系统,每个bug属 ...

  9. poj 2096 Collecting Bugs - 概率与期望 - 动态规划

    Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material stu ...

随机推荐

  1. 【LeetCode】Unique Binary Search Trees II 异构二叉查找树II

    本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4048209.html 原题: Given n, generate all struc ...

  2. flex布局学习总结

    最近项目主要是小程序,小程序里面的布局主要采用flex布局,之前对flex 布局只是稍作了解,总结下flex 布局的常用套路 容器 Flex是Flexible Box的缩写,意为"弹性布局& ...

  3. en_e outtest2

    e 1◆ e i: ə ɜː e I   2◆ ei ey ei i:   3◆ eer ɪə   4◆ ee i:   5◆ er ə   6◆ ere ɪə eə   7◆ ea ɪə i: ə ...

  4. iddea代码调试debug篇

    代码调试debug篇 主要看图,看图一目了然.  断点的设定和eclipse一样,只要点一下就可以,下面是我设定的几个断点,再下面的三个窗口是用来调试代码的,这个和eclipse类似 调试常用的快捷键 ...

  5. javascript开发HTML5游戏--斗地主(单机模式part2)

    最近学习使用了一款HTML5游戏引擎(青瓷引擎),并用它尝试做了一个斗地主的游戏,简单实现了单机对战和网络对战,代码可已放到github上,在此谈谈自己如何通过引擎来开发这款游戏的. 客户端代码 服务 ...

  6. kettle 发邮件带附件

    新建一个job,主要用到的组件有两个,如下图: 首先点击下图的文件,选择你要做为邮件附件的文件.选完后会在前辈的文件.目录中显示.然后点击增加,会下面文件列表中显示已经添加的文件(涂黄色的部分) 按下 ...

  7. 练习vue(class,style属性)

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. Sring类的codePointAt()方法

    工作中遇到一段代码 private static String getClassNameWithoutPackage(Class cl) { String className = cl.getName ...

  9. Mysql Innodb 表碎片整理

    一.为什么会产生碎片 简单的说,删除数据必然会在数据文件中造成不连续的空白空间,而当插入数据时,这些空白空间则会被利用起来.于是造成了数据的存储位置不连续,以及物理存储顺序与理论上的排序顺序不同,这种 ...

  10. 使用 ADOX 将 Table 添加到 Catalog 时报“类型无效”的原因和解决方法

    http://blog.csdn.net/kfhzy/article/details/6020283 http://blog.csdn.net/kfhzy/article/details/602054 ...