概率dp入門
/*poj 2096 第一道概率dp看別人的思路,不過總算理解為什麼求期望從後往前了 地址:http://blog.csdn.net/morgan_xww/article/details/6774708 */ #include<stdio.h> #include<string.h> #define N 1100 double dp[N][N]; int main() { int n,s,i,j; while(scanf("%d%d",&n,&s)!=EOF) { memset(dp,0,sizeof(dp)); for(i=n;i>=0;i--) for(j=s;j>=0;j--) { if(i==n&&j==s)continue; dp[i][j]=(n*s+dp[i+1][j]*(n-i)*j+dp[i][j+1]*i*(s-j)+dp[i+1][j+1]*(n-i)*(s-j))/(n*s-i*j); } printf("%.4f\n",dp[0][0]); } return 0;}
/* hdu 3853 有一個坑,到達自身的概率為1的話,就不用加到上一個 */ #include<stdio.h> #include<math.h> #include<string.h> #define eps 1e-10 #define N 1100 struct node { double a,b,c; }ma[N][N]; double dp[N][N]; int main() { int n,m,i,j; while(scanf("%d%d",&n,&m)!=EOF) { for(i=0;i<n;i++) for(j=0;j<m;j++) scanf("%lf%lf%lf",&ma[i][j].a,&ma[i][j].b,&ma[i][j].c); memset(dp,0,sizeof(dp)); for(i=n-1;i>=0;i--) for(j=m-1;j>=0;j--) { if(i==n-1&&j==m-1)continue; if(fabs(1-ma[i][j].a)<eps)continue;//對於不能到達的不用計算 dp[i][j]=(dp[i+1][j]*ma[i][j].c+dp[i][j+1]*ma[i][j].b+2)/(1-ma[i][j].a); } printf("%.3f\n",dp[0][0]); } return 0;}
/* hdu 4405 只需處理以下可以直接到達的關係就可以了 */ #include<stdio.h> #include<string.h> #include<map> using namespace std; #define N 110000 double dp[N]; int f[N]; int main() { int n,m,i,a,b; double kk; while(scanf("%d%d",&n,&m),n||m) { memset(dp,0,sizeof(dp)); memset(f,-1,sizeof(f)); while(m--) { scanf("%d%d",&a,&b); f[a]=b; } for(i=n-1;i>=0;i--) { if(f[i]==-1) dp[i]=dp[i+1]/6+dp[i+2]/6+dp[i+3]/6+dp[i+4]/6+dp[i+5]/6+dp[i+6]/6+1.0; else dp[i]=dp[f[i]]; } printf("%.4f\n",dp[0]); } return 0;}
/*
sgu495
m個人是獨立的
n個禮物每一個都不被選中的概率是(n-1)/n;
n個禮物都不被選中的期望為n*pow(d,m);
*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#define N 1100
int main() {
int n,m;
double d,sum;
while(scanf("%d%d",&n,&m)!=EOF) {
d=(double)(n-1)/n;
sum=1.0*n-1.0*n*pow(d,m);
printf("%.10f\n",sum);
}
return 0;}
/*
sgu495
第二種做法很好
m個人是獨立的
從人考慮:
每個人都有可能得到1個禮物,但是第i個人得到1個禮物的概率與第i-1個人得到禮物的概率有關
如果第i-1個人的到禮物,那麼第i個人得到1個禮物的概率為dp[i-1]*(dp[i-1]-1.0/n);
如果第i-1個人沒有得到,那麼第i個人得到1個禮物的概率為dp[i-1]*(1-dp[i-1]);
*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#define N 110000
double dp[N];
int main() {
int n,m,i;
double d,sum;
while(scanf("%d%d",&n,&m)!=EOF) {
dp[1]=1.0;sum=0;
for(i=2;i<=m;i++) {
dp[i]=1*((1-dp[i-1])*dp[i-1])+1*(dp[i-1]*(dp[i-1]-1.0/n));
sum+=dp[i];
}
printf("%.10f\n",sum+1.0);
}
return 0;}
/*
cf 148D
理解概率的從前到後處理很好!
先確定邊界,從邊界出發進行dp
題意:王妃和龍輪流從袋子裡那老鼠,如果王妃先拿到白老鼠,如果龍先拿到白老鼠那麼龍贏,那麼王菲贏,如果兩人都沒有取到
白老鼠那麼龍贏.
求概率從前往後,先處理邊界,
參考部落格:http://www.cnblogs.com/kuangbin/archive/2012/10/04/2711184.html
dp[i][j]代表剩餘i只白鼠j只黒鼠時王妃贏的概率
三種情況王妃贏
1.王妃抓到一隻白老鼠,王菲贏了i/(i+j);
2.w王妃抓到一隻黑老鼠,龍抓到一隻黑老鼠,跑了一隻黑老鼠,那麼贏的概率需要用到dp[i][j-3];
1.0*j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2)*dp[i][j-3];
3.王菲抓到一隻黑老鼠,龍抓到一隻黑老鼠,跑了一隻白老鼠,那麼贏的概率需要用到dp[i-1][j-2]
1.0*j/(i+j)*(j-1)/(i+j-1)*i/(i+j-2)*dp[i-1][j-2]
並且保證合法
*/
#include<stdio.h>
#include<string.h>
#define N 1100
double dp[N][N];
int main() {
int n,m,i,j;
while(scanf("%d%d",&n,&m)!=EOF) {
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)dp[i][0]=1;
for(i=1;i<=m;i++)dp[0][i]=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++) {
dp[i][j]+=1.0*i/(i+j);
if(j>=2)
dp[i][j]+=1.0*j/(i+j)*(j-1)/(i+j-1)*i/(i+j-2)*dp[i-1][j-2];
if(j>=3)
dp[i][j]+=1.0*j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2)*dp[i][j-3];
}
printf("%.10f\n",dp[n][m]);
}
return 0;}
/*
題意:
一隻吸血鬼,有n條路給他走,每次他隨機走一條路,
每條路有個限制,如果當時這個吸血鬼的攻擊力大於
等於某個值,那麼就會花費t天逃出去,否則,花費1天
的時間,並且攻擊力增加,問他逃出去的期望天數
因為可能有許多種情況,並且可以重複出現,所以記憶化搜尋
比如在某些條件下f+a[1]+a[2]和f+a[2]+a[1],會重複出現所以記憶
*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#define N 21000//因為f和a[i]的值都是10000所以
double dp[N];
int a[N];
int n;
double dfs(int f)
{
if(dp[f]>0)return dp[f];
int i;
for(i=1; i<=n; i++)
{
if(f>a[i])
{
double temp=(1.0+sqrt(5.0))/2*a[i]*a[i];
int t=(int)temp;
dp[f]+=1.0*t*1.0/n;
}
else
dp[f]+=(1.0+dfs(f+a[i]))*1.0/n;//當前能夠走出去的天數由f+a[i]後的期望天數+1乘於概率得到
}
return dp[f];
}
int main()
{
int m,i;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1; i<=n; i++)
scanf("%d",&a[i]);
memset(dp,0,sizeof(dp));
printf("%.3f\n",dfs(m));
}
return 0;
}
/*
poj 3744 求概率
題意:偵察兵YYF要通過一條布有地雷的路,
他從1出發,每次有p的機率前進1格,
1-p的機率前進兩個,現已知所有地雷的位置,求YYF不踩中地雷並且通過這條雷區路的的概率
解:首先特判如果1的點是雷的話直接炸死
易知初始化dp[0]=0;dp[1]=1;
dp[i]=dp[i-1]*p+dp[i-2]*(1-p);
因為i很大所以用矩陣快速冪解
構建矩陣
|a0,a1|*|0 1-p| =|a1 a2|
|1 p |
*/
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 10
int aa[N];
struct matrix{
double mat[5][5];
};
matrix matmul(matrix a,matrix b) {
int i,j,k;
matrix c;
memset(c.mat,0,sizeof(c.mat));
for(i=0;i<2;i++)
for(j=0;j<2;j++)
for(k=0;k<2;k++)
c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
return c;
}
matrix matpow(matrix a,int k) {
matrix b;
int i;
memset(b.mat,0,sizeof(b.mat));
for(i=0;i<2;i++)
b.mat[i][i]=1;
while(k) {
if(k&1)b=matmul(a,b);
a=matmul(a,a);
k>>=1;
}
return b;
}
int main() {
int n,i,k,flag;
double p;
while(scanf("%d%lf",&n,&p)!=EOF) {
flag=0;
for(i=1;i<=n;i++) {
scanf("%d",&aa[i]);
if(aa[i]==1)
flag=1;
}
if(flag) {
printf("%.7f\n",0);
continue;
}
sort(aa+1,aa+1+n);
matrix a,b;
memset(a.mat,0,sizeof(a.mat));
a.mat[0][0]=0;
a.mat[0][1]=1.0;
b.mat[0][0]=0;
b.mat[0][1]=1-p;
b.mat[1][0]=1.0;
b.mat[1][1]=p;
aa[0]=1;
for(i=1;i<=n;i++) {
k=aa[i]-aa[i-1]-1;
a=matmul(a,matpow(b,k));
a.mat[0][0]=a.mat[0][1];
a.mat[0][1]=0;
}
a=matmul(a,matpow(b,1));
printf("%.7f\n",a.mat[0][1]);
}
return 0;}
相關推薦
[填坑]期望概率DP 入門級別
using pri == ble for ostream cst space 入門級 poj 2096 Collecting Bugs 期望DP 這道題是最入門的期望DP,然而我並不是很會做,甚至連題都沒看懂。。(其實是English不好 相信我) 題解: 在這裏有s
【NOIP2016提高】換教室題解——作為概率DP入門題
題目:luogu1850. 題目大意:給定v個教室,教室之間有e條無向邊邊,保證連通.現在有n組教室,每組有一個被欽定的教室和一個可以替換的教室,現在給你m次替換教室的機會,以及當你打算替換掉一組教室時成功的概率,讓你求最後依次經過你選擇的教室的期望路徑最小值. 我覺得我的題目大意好像解
hdu3853之概率dp入門
LOOPS Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 125536/65536 K (Java/Others) Total Submission(s): 1
【概率DP入門】
http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710606.html 有關概率和期望問題的研究 摘要 在各類資訊學競賽中(尤其是ACM競賽中),經常出現一些與概率和期望有關的題目。這類題目需要較高的數學水平和一定
概率dp入門
/*poj 2096 第一道概率dp看別人的思路,不過總算理解為什麼求期望從後往前了 地址:http://blog.csdn.net/morgan_xww/article/details/677470
HDU 4405(概率dp入門)
說是概率DP,其實主要是求概率和期望的問題 說到DP總要有狀態,每種狀態可能有多種子狀態 一般的DP是這樣:在DP過程中,當前狀態必然是由多個子狀態中的最優的轉移而來 所以一般的DP求的是最優的結果 而概率不需要最優,而是實際概率 所以概率DP最大的區別在於:在DP
poj2096 概率dp入門____期望
Description Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material stuff, he collects so
Discovering Gold(概率dp 期望入門)
題意 有一排洞穴,你在第一個洞穴,可以獲得該洞穴的黃金,然後擲標有1-6的骰子, 是幾就往下走幾步,並得到該洞穴的黃金。 當離終點小於6步且不合法時就重擲直到合法為止。 求起點出發的黃金的期望。 題解 概率dp入門題。 考慮到自己dp比較菜,概率dp更菜
bzoj1076(概率與期望dp入門)
題目大意:給定k次彈出寶物的機會,每次隨機彈出n種寶物的機會,如果吃過這種寶物的所有前提寶物就可以吃這種寶物,求最優策略的期望得分 看到資料範圍果斷狀壓DP- - 不看資料範圍害死人- - 至於吃還是不吃 這是個問題 對於這種最優策略的期望DP 我們一般都是從後往前推 列舉
骰子 (入門概率DP)
【概率】骰子 時間限制: 1 Sec 記憶體限制: 128 MB 提交: 14 解決: 10 [提交] [狀態] [討論版] [命題人:admin] 題目描述 眾所周知,骰子是一個六面分別刻有一到六點的立方體,每次投擲骰子,從理論上講得到一點到六點的概率都是1/6。
概率DP【入門】
題意: 2個人分別有AB的血數,輪流扔骰子,數小的自減一血,平的不變,誰先到減0, 誰輸,問A贏的概率。 題解: 考慮平局的出現對局面沒有影響,因此把平局規約到非平局裡即可,對於每一次p1表示A贏,p2表示B贏,p=1-p1-p2表示平局,A贏的概率為p1+p*p1+p
ACM-概率dp之入門
概率dp其實就是利用動態規劃的思想去解決概率、期望等題目,本質上來說與普通的dp沒有太大的區別,只是可能會涉及到一些概率論方面的知識。so,練題吧...... 入門題1,HDOJ:3853,時空轉移(點選開啟連結),題目如下: LOOPS Time Limit: 150
hdu 2089 不要62 數位DP入門
dfs += ret memset tro int 入門 space spa 題目鏈接: http://acm.hdu.edu.cn/showproblem.php?pid=2089 題意: 統計區間 [a,b] 中不含 4 和 62 的數字有多少個。 思路: 學習了數位d
狀壓DP入門——鋪磚塊
ont 輸出 fin load www ret mil times set 題目描述 現有n*m的一塊地板,需要用1*2的磚塊去鋪滿,中間不能留有空隙。問這樣方案有多少種 輸入 輸入n,m(1<=n, m<=11) 有多組輸入數據,以m=n=0結束
概率DP——求期望
ble double 四種 bug 導出 -i 鏈接 emc str 一般求期望類題目都是倒著來做的,dp[i]表示i狀態下要達到要求狀態的期望值,於是dp[0]就是我們要找的答案,我們可以通過此來推狀態轉移方程,可以得到dp[i]=Σ(dp[k>i]*p[k])
[Codefoeces398B]Painting The Wall(概率DP)
cstring fine 傳送門 printf ring clu 綠色 type -i 題目大意:一個$n\times n$的棋盤,其中有$m$個格子已經被染色,執行一次染色操作(無論選擇的格子是否已被染色)消耗一個單位時間,染色時選中每個格子的概率均等,求使每一行、
{dp入門}
code 記憶 題目 memset mem bsp 記憶化 span space 之前一直比較恐懼dp的題,暑假之前好好從頭補一下。 題目鏈接:HihoCoder - 1037 數字三角形 dp[i][j]表示到第i層第j個房間時累計收集到的最大值,從上到下記憶化搜索
[Codeforces Round #284 (Div. 1) B]Name That Tune(概率Dp)
題意 red return 聽歌識曲 blog 應該 n) mean begin Description It turns out that you are a great fan of rock band AC/PE. Peter learned that and
【概率dp】【滾動數組】CDOJ1652 都市大飆車
ima 空間 pac names puts 都市 for 1.0 images 轉移方程很顯然。 因為是多段圖模型,所以可以滾動數組優化一維空間。 #include<cstdio> #include<cstring> using namespac
【數位dp入門】【HDU2089】62
ret main ont scanf size hdu2089 con %d tmp 為了我的點歪的技能樹…… 所以開始補一些sb的東西…… #include<bits/stdc++.h> typedef long long ll; using namespa