标签:
题意:
n个人,开始有一个容量为k得背包,击败一个人背包可以获得一定容量或得到一个财富(放入背包内),给出击败每个人的概率,求至少击败l个人,且背包容量大于获得的总财富值的概率
分析:
状态好确定,dp[i][j][k]表示前i个人击败j个背包容量是k是的概率,求概率正推,要注意这时背包容量能为负,我们把容量都加上B。
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<11 #define All 1,N,1 #define read freopen("in.txt", "r", stdin) #define B 201 const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; double dp[210][210][2*B+10]; int a[210],p[210]; int n,l,k; void solve(){ memset(dp,0,sizeof(dp)); dp[0][0][B+k]=1; for(int i=1;i<=n;++i) for(int j=0;j<=i;++j) for(int k=0;k<=2*B;++k) { dp[i][j][k]+=dp[i-1][j][k]*(1-p[i]/100.0);//未击败第i个人 if(a[i]==-1){ if(k>0)//必须能放下一个财富 dp[i][j+1][k-1]+=dp[i-1][j][k]*(p[i]/100.0); } else{ if(k+a[i]>2*B) dp[i][j+1][2*B]+=dp[i-1][j][k]*(p[i]/100.0); else dp[i][j+1][k+a[i]]+=dp[i-1][j][k]*(p[i]/100.0); } }
//符合条件的情况的概率和 double total=0.0; for(int j=l;j<=n;++j) for(int k=B;k<=2*B;++k) total+=dp[n][j][k]; printf("%.12lf\n",total); } int main() { while(~scanf("%d%d%d",&n,&l,&k)){ for(int i=1;i<=n;++i) scanf("%d",&p[i]); for(int i=1;i<=n;++i) scanf("%d",&a[i]); solve(); } return 0; }
Codeforces 167B Wizards and Huge Prize(概率dp)
标签:
原文地址:http://www.cnblogs.com/zsf123/p/4777102.html