概率期望总结(题目合集)

怼烎@ 2024-04-17 15:17 139阅读 0赞

1、2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) E - Explosion Exploit(dfs+概率)

题意:我方n人,血量已知,对方m人,血量已知。现在有d点伤害,一点一点扣,每次伤害对所有活着的人的概率相同。问d次伤害后对面全死的概率。

分析:好题,把概率和dfs结合在了一起,概率题做的少,不擅长。题目数据范围很小,可以直接记忆化搜索,记录每个血量下的人数,用12位十进制数表示双方的状态,需要注意状态转移的方式。

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. map<ll,double> mp;
  5. int cnt[2][10];
  6. ll get_sta(){
  7. ll ans=0;
  8. for(int i=1;i<=6;i++) ans*=10,ans+=cnt[1][i];
  9. for(int i=1;i<=6;i++) ans*=10,ans+=cnt[0][i];
  10. return ans;
  11. }
  12. double dfs(ll sta,int heath){
  13. if(mp[sta]) return mp[sta];///记忆化
  14. if(sta<1000000) return 1;
  15. if(heath==0) return 0;
  16. int sum=0;///总人数
  17. for(int i=0;i<2;i++)
  18. for(int j=1;j<=6;j++)
  19. sum+=cnt[i][j];
  20. double ans=0;
  21. for(int i=0;i<2;i++){
  22. for(int j=1;j<=6;j++){
  23. if(!cnt[i][j]) continue;
  24. cnt[i][j]--;
  25. cnt[i][j-1]++;
  26. ll nowsta=get_sta();
  27. double res=dfs(nowsta,heath-1);
  28. cnt[i][j]++;
  29. cnt[i][j-1]--;
  30. mp[nowsta]=res;
  31. /// 注意转移方程 当前健康值人数/总人数*上一次转移过来的状态值
  32. ans+=1.0*cnt[i][j]/sum*res;
  33. }
  34. }
  35. return ans;
  36. }
  37. int main(){
  38. int n,m,d,h;
  39. scanf("%d%d%d",&n,&m,&d);
  40. for(int i=1;i<=n;i++){
  41. scanf("%d",&h);
  42. cnt[0][h]++;
  43. }
  44. for(int i=1;i<=m;i++){
  45. scanf("%d",&h);
  46. cnt[1][h]++;
  47. }
  48. double ans=dfs(get_sta(),d);
  49. printf("%.8f\n",ans);
  50. }

发表评论

表情:
评论列表 (有 0 条评论,139人围观)

还没有评论,来说两句吧...

相关阅读

    相关 博弈论总结题目

    题意:两个人玩游戏,有 n 块石头,初始坐标为(x,y),一次操作可以将一块石头移动到(x - u,y),(x,y - u)或者(x - u,y - u),坐标为(0,0)的