概率dp 二维dp 两个dp方程 1400

假设白天有n(1<=n<=1000)分钟,每分钟妹子快乐的概率分别为a1,a2…an,(0<=ai<=1),假如这n分钟内有k(0<=k<=n)分钟妹子是快乐的,那么liuxx就可能有晚上,否则妹子晚上会回家,求liuxx有晚上的概率
全局变量 清0 dp[i][j]前i分钟有j分钟快乐的概率
每天两种情况 快乐或者不快乐
a1-an 每天快乐的概率

double dp[1005][1005];	//前i分钟有j分钟 妹子快乐的概率 
double a[1005];	//1000分钟每一分钟妹子快乐的概率 

初始化 注意边界dp[0][0]=1

dp方程式
1.最好写法 前0分钟有0分钟是快乐的

for(int i=0;i<=n-1;i++)
	{
		for(int j=0;j<=i;j++)
		{
			dp[i+1][j+1]+=dp[i][j]*a[i+1];//下一分钟创造快乐
			dp[i+1][j]+=dp[i][j]*(1-a[i+1]);//下一分钟没有创造快乐 
		}
	}
	cout<<dp[n][k]<<endl;
i=0 j=0
	dp[1][1]+=dp[0][0]*a[1]=a[1];
	dp[1][0]+=dp[0][0]*(1-a[1])=1-a[1];
i=1 j=0
	dp[2][1]+=dp[1][0]*a[2]=(1-a[1])*a[2];
	dp[2][0]+=dp[1][0]*(1-a[2])=(1-a[1])*(1-a[2]);
i=1 j=1
	dp[2][2]+=dp[1][1]*a[2]=a[1]*a[2];//下一分钟创造快乐 1,1->2,2
	dp[2][1]+=dp[1][1]*(1-a[2])=a[1]*(1-a[2]);	//下一分钟不创造快乐延续j
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<cctype>
using namespace std;

#define PI acos(-1.0)
#define mp make_pair
#define forn(i,n) for(int i=0;i<n;i++)
#define for1(i,n) for(int i=1;i<=n;i++) 
#define rep(i,a,n)  for(int i=a;i<n;i++)
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

const int INF32M=0x3f3f3f3f;
const ll INF64M=0x3f3f3f3f3f3f3f3f;
const int maxn=2e5+5;
const int mod=1e9+7;

int gcd(int a,int b)
{
	return b!=0?gcd(b,a%b):a;
}
double dp[1005][1005];	//前i分钟有j分钟 妹子快乐的概率 
double a[1005];	//1000分钟每一分钟妹子快乐的概率 
int main()
{
	ios::sync_with_stdio(false);
	int n,k;
	cin>>n>>k;
	memset(dp,0,sizeof dp);
	
	for(int i=1;i<=n;i++)
		cin>>a[i];
	dp[0][0]=1;
//	for(int i=1;i<=n;i++)
//		dp[i][0]=dp[i-1][0]*(1-a[i]);

	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			dp[i][j]+=dp[i-1][j-1]*a[i];
			dp[i][j-1]+=dp[i-1][j-1]*(1-a[i]);
		}
	}
	
	cout<<dp[n][k]<<endl;	//前n分钟有k分钟快乐的概率 
	return 0;
}

答案分析:

/* 	i=1 j=1
	dp[1][1]+=dp[0][0]*a[1]=a[1]		//度过1分钟 创造出多一份的快乐 
	dp[1][0]+=dp[0][0]*(1-a[1])=1-a[1]	 
	i=2 j=1
	dp[2][1]+=dp[1][0]*a[2]=(1-a[1])*a[2]	//前2分钟有1分钟是快乐的 两种情况 
	dp[2][0]+=dp[1][0]*(1-a[2])=(1-a[1])*(1-a[2])
	i=2 j=2
	dp[2][2]+=dp[1][1]*a[2]=a[1]*a[2]
	dp[2][1]+=dp[1][1]*(1-a[2])=a[1]*(1-a[2])	//延续1分钟没有创造多一份快乐 
	*/ 
/* n=3 k=1 0.5 0.5 0.25
	i=3 j=1
1	dp[3][1]+=dp[2][0]*a[3]=(1-a[1])*(1-a[2])*a[3](第i分钟创造快乐) 
	i=3 j=2
2	dp[3][1]+=dp[2][1]*(1-a[3])=[(1-a[1])*a[2]+a[1]*(1-a[2])]*(1-a[3])	第i分钟未创造快乐 
	相当于 3分钟 只有第一分钟快乐 或 2 或 3
1	1/2*1/2*1/4=1/16
2 	[1/2*1/2+1/2*1/2]*3/4=1/2*3/4=3/8
1+2 1/16+6/16=7/16=0.4375
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值