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. 追加XML

    追加有两种情况,这个文档可能存在,也可能不存在 XmlDocument doc = new XmlDocument();XmlElement books; //将books声明在外边这样后面的代码才可 ...

  2. 一篇分析诊断被&quot;hang&quot;住数据库的资料(Oracle Performance Diagnostic Guide——Hang/Locking)

    该资料已上传至本人QQ群空间,如需该资料,可到本人QQ群空间查找.下面贴表文本: Oracle Performance Diagnostic GuideHang/LockingVersion 3.1. ...

  3. 关于rowid的函数

    1. select dbms_rowid.rowid_object(rowid) object_id, dbms_rowid.rowid_relative_fno(rowid) file_id, db ...

  4. Oracle/MySQL decimal/int/number 转字符串

    有时客户需要流水数据,当导出为excel的时候,客户编号等很长数字的栏位,被excel变成科学记数法,无法正常查看. 因此,需要将Oracle/MySQL中的decimal/int 转 varchar ...

  5. TClientDataSet的FileName属性

    读取cds文件数据. FileName一定要在设计时输入,否则程序运行时,不会自动读取cds文件. 因为FORM创建时,数据集组件也相应创建,如果是在运行时 设置FileName,那么是在数据集组件创 ...

  6. POJ 2242 The Circumference of the Circle

    做题回顾:用到海伦公式,还有注意数据类型,最好统一 p=(a+b+c)/2; s=sqrt(p*(p-a)*(p-b)*(p-c));//三角形面积,海伦公式 r=a*b*c/(4*s);//这是外接 ...

  7. 用正则表达式匹配用rdf3x处理过后的TTL格式文档

    1.比如下面这个用rdf3x处理过后的TTL文档片段: 注意缩进的是两个空格 <http://rdf.ebi.ac.uk/resource/chembl/target/CHEMBL2363853 ...

  8. Java——IO类,字符流读数据

    body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2p ...

  9. Linux就该这么学笔记

    https://www.linuxprobe.com/========================================================================= ...

  10. [python] 基于词云的关键词提取:wordcloud的使用、源码分析、中文词云生成和代码重写

    1. 词云简介 词云,又称文字云.标签云,是对文本数据中出现频率较高的“关键词”在视觉上的突出呈现,形成关键词的渲染形成类似云一样的彩色图片,从而一眼就可以领略文本数据的主要表达意思.常见于博客.微博 ...