『概率DP』守卫者的挑战

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Ronaldo7_ZYB/article/details/89526678

题目描述

打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜寻着关押applepi的监狱的所在地。突然,眼前一道亮光闪过。“我,Nizem,是黑魔法圣殿的守卫者。如果你能通过我的挑战,那么你可以带走黑魔法圣殿的地图……”瞬间,队员们被传送到了一个擂台上,最初身边有一个容量为K的包包。

擂台赛一共有N项挑战,各项挑战依次进行。第i项挑战有一个属性ai,如果ai>=0,表示这次挑战成功后可以再获得一个容量为ai的包包;如果ai=-1,则表示这次挑战成功后可以得到一个大小为1 的地图残片。地图残片必须装在包包里才能带出擂台,包包没有必要全部装满,但是队员们必须把 【获得的所有的】地图残片都带走(没有得到的不用考虑,只需要完成所有N项挑战后背包容量足够容纳地图残片即可),才能拼出完整的地图。并且他们至少要挑战成功L次才能离开擂台。

队员们一筹莫展之时,善良的守卫者Nizem帮忙预估出了每项挑战成功的概率,其中第i项挑战成功的概率为pi%。现在,请你帮忙预测一下,队员们能够带上他们获得的地图残片离开擂台的概率。

题目大意

n n 个挑战,每一个挑战成功后可以赢得一份数 a i a_i ,求在赢得至少 L L 场的情况下赢得的 a i > 0 \sum a_i>0 .这样称之为成功,在给定每一个挑战成功的基础下求解最后成功的概率。

题解

做完这道题以后对概率有了一份更加深入的理解。我们队概率可以这样理解,对于每一个转移的状态看作是一份树形的结构,树的根节点的概率为1,接下来每一个节点的概率都均分这一个1的概率。而且每一份节点的概率为转移到这一个节点的概率之和而不是相乘。

捋顺概率的意义以后我们就可以来解决这一道题。

我们设 f i , j , k f_{i,j,k} 表示到了第 i i 个挑战,赢了 j j 个碎片,背包容量为 k k 的概率。

我们可以根据当前状态去扩展未来状态.

如果第 i + 1 i+1 个挑战成功了,
f i + 1 , j + 1 , k + a [ i + 1 ]   + = f i , j , k p ( i + 1 ) f_{i+1,j+1,k+a[i+1]}\ += f_{i,j,k}*p(i+1)

如果第 i + 1 i+1 个挑战失败了,
f i + 1 , j , k   + =   f i , j , k ( i p ( i + 1 ) ) f_{i+1,j,k}\ +=\ f_{i,j,k}*(i-p(i+1))

然后你会发现 k k 特别大,但是挑战只有 n n 个,因此当容量超过 n n 个的时候我们可以将容量设置为 n n ;且 k k 最大的枚举量也为 n n 。正确性可以保证,因为答案只是累加的并没有单独的作用,因为累加到 n n 上不存在任何问题。

还有一个坑就是背包容量可以是负数,需要加上偏移量。

代码如下:

#include <bits/stdc++.h>

using namespace std;

int N,L,R,K;
int a[300];
double p[300];
double f[205][205][500];

inline int F(int x)
{
    if (x>N) x = N;
	return x+205;
}

int main(void)
{
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	cin>>N>>L>>K;
	for (int i=1;i<=N;++i) 
	{
		int x;
		cin>>x;
		p[i] = x/100.0;
	}
	for (int i=1;i<=N;++i) cin>>a[i];
	f[0][0][F(K)] = 1;
	for (int i=0;i<N;++i) 
	    for (int j=0;j<=i;++j)
	        for (int k=-N;k<=N;++k) 
	            f[i+1][j+1][F(k+a[i+1])] += f[i][j][F(k)]*p[i+1],
	            f[i+1][j][F(k)] += f[i][j][F(k)]*(1-p[i+1]);
	double ans = 0.0;
	for (int j=L;j<=N;++j)
	    for (int k=0;k<=N;++k)
	        ans += f[N][j][F(k)];
	printf("%.6lf",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Ronaldo7_ZYB/article/details/89526678