zoukankan      html  css  js  c++  java
  • [BZOJ4832]抵制克苏恩(概率期望DP)

    方法一:倒推,最常规的期望DP。f[i][a][b][c]表示还要再攻击k次,目前三种随从个数分别为a,b,c的期望攻击英雄次数,直接转移即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #define rep(i,l,r) for (int i=l; i<=r; i++)
     6 typedef long long ll;
     7 using namespace std;
     8 
     9 const int N=60,M=10;
    10 int n,a,b,c,T;
    11 double f[N][M][M][M];
    12 
    13 int main(){
    14     freopen("bzoj4832.in","r",stdin);
    15     freopen("bzoj4832.out","w",stdout);
    16     rep(i,1,50) rep(a,0,7) rep(b,0,7-a) rep(c,0,7-a-b){
    17         int t=(a+b+c<7);
    18         f[i][a][b][c]+=(f[i-1][a][b][c]+1)/(a+b+c+1);
    19         if (a) f[i][a][b][c]+=f[i-1][a-1][b][c]*a/(a+b+c+1);
    20         if (b) f[i][a][b][c]+=f[i-1][a+1][b-1][c+t]*b/(a+b+c+1);
    21         if (c) f[i][a][b][c]+=f[i-1][a][b+1][c-1+t]*c/(a+b+c+1);
    22     }
    23     for (scanf("%d",&T); T--; )
    24         scanf("%d%d%d%d",&n,&a,&b,&c),printf("%.2lf
    ",f[n][a][b][c]);
    25     return 0;
    26 }

    方法二:用顺推做期望DP,f[x]=(f[k]+w[k][x])*p[k][x],其中k是所有能到达x的状态,w[k][x]表示这个转移的代价(攻击随从时为0,攻击英雄时为1),p[k][x]是x由k得到的概率(注意不是k转移到x的概率)。

    P(x由k得到)=P(k)*P(k转移到x)/P(x),同时维护p和f即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #define rep(i,l,r) for (int i=l; i<=r; i++)
     6 typedef long long ll;
     7 using namespace std;
     8 
     9 const int N=60,M=10;
    10 const double eps=1e-10;
    11 int n,a,b,c,T;
    12 double p[N][M][M][M],f[N][M][M][M];
    13 
    14 int main(){
    15     freopen("bzoj4832.in","r",stdin);
    16     freopen("bzoj4832.out","w",stdout);
    17     for (scanf("%d",&T); T--; ){
    18         memset(p,0,sizeof(p)); memset(f,0,sizeof(f));
    19         scanf("%d%d%d%d",&n,&a,&b,&c); p[0][a][b][c]=1; double ans=0;
    20         rep(i,0,n-1) rep(a,0,7) rep(b,0,7-a) rep(c,0,7-a-b){
    21             int t=(a+b+c<7);
    22             p[i+1][a-1][b][c]+=p[i][a][b][c]*a/(a+b+c+1);
    23             p[i+1][a+1][b-1][c+t]+=p[i][a][b][c]*b/(a+b+c+1);
    24             p[i+1][a][b+1][c-1+t]+=p[i][a][b][c]*c/(a+b+c+1);
    25             p[i+1][a][b][c]+=p[i][a][b][c]/(a+b+c+1);
    26         }
    27         rep(i,0,n-1) rep(a,0,7) rep(b,0,7-a) rep(c,0,7-a-b){
    28             int t=(a+b+c<7); double x=f[i][a][b][c]*p[i][a][b][c];
    29             if (p[i+1][a-1][b][c]>eps)
    30                 f[i+1][a-1][b][c]+=x*a/((a+b+c+1)*p[i+1][a-1][b][c]);
    31             if (p[i+1][a+1][b-1][c+t]>eps)
    32                 f[i+1][a+1][b-1][c+t]+=x*b/((a+b+c+1)*p[i+1][a+1][b-1][c+t]);
    33             if (p[i+1][a][b+1][c-1+t]>eps)
    34                 f[i+1][a][b+1][c-1+t]+=x*c/((a+b+c+1)*p[i+1][a][b+1][c-1+t]);
    35             if (p[i+1][a][b][c]>eps)
    36                 f[i+1][a][b][c]+=(f[i][a][b][c]+1)*p[i][a][b][c]/((a+b+c+1)*p[i+1][a][b][c]);
    37         }
    38         rep(a,0,7) rep(b,0,7-a) rep(c,0,7-a-b) ans+=f[n][a][b][c]*p[n][a][b][c];
    39         printf("%.2lf
    ",ans);
    40     }
    41     return 0;
    42 }

    方法三:同样用顺推,但这里的f是上面的f*p,转移时要考虑期望的定义

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #define rep(i,l,r) for (int i=l; i<=r; i++)
     6 typedef long long ll;
     7 using namespace std;
     8 
     9 const int N=60,M=10;
    10 const double eps=1e-10;
    11 int n,a,b,c,T;
    12 double p[N][M][M][M],f[N][M][M][M];
    13 
    14 int main(){
    15     for (scanf("%d",&T); T--; ){
    16         memset(p,0,sizeof(p)); memset(f,0,sizeof(f));
    17         scanf("%d%d%d%d",&n,&a,&b,&c); p[0][a][b][c]=1; double ans=0;
    18         rep(i,0,n-1) rep(a,0,7) rep(b,0,7-a) rep(c,0,7-a-b){
    19             int t=(a+b+c<7);
    20             p[i+1][a-1][b][c]+=p[i][a][b][c]*a/(a+b+c+1);
    21             p[i+1][a+1][b-1][c+t]+=p[i][a][b][c]*b/(a+b+c+1);
    22             p[i+1][a][b+1][c-1+t]+=p[i][a][b][c]*c/(a+b+c+1);
    23             p[i+1][a][b][c]+=p[i][a][b][c]/(a+b+c+1);
    24         }
    25         rep(i,0,n-1) rep(a,0,7) rep(b,0,7-a) rep(c,0,7-a-b){
    26             int t=(a+b+c<7);
    27             if (p[i+1][a-1][b][c]>eps)
    28                 f[i+1][a-1][b][c]+=f[i][a][b][c]*a/(a+b+c+1);
    29             if (p[i+1][a+1][b-1][c+t]>eps)
    30                 f[i+1][a+1][b-1][c+t]+=f[i][a][b][c]*b/(a+b+c+1);
    31             if (p[i+1][a][b+1][c-1+t]>eps)
    32                 f[i+1][a][b+1][c-1+t]+=f[i][a][b][c]*c/(a+b+c+1);
    33             if (p[i+1][a][b][c]>eps)
    34                 f[i+1][a][b][c]+=(f[i][a][b][c]+p[i][a][b][c])/(a+b+c+1);
    35         }
    36         rep(a,0,7) rep(b,0,7-a) rep(c,0,7-a-b) ans+=f[n][a][b][c];
    37         printf("%.2lf
    ",ans);
    38     }
    39     return 0;
    40 }
  • 相关阅读:
    HDU 1711 Number Sequence
    PAT L2-016 愿天下有情人都是失散多年的兄妹
    PAT L2-024 部落
    斜率优化DP小结(含凸优化)
    jzoj 4475. 【GDOI2016模拟4.25】征途
    jzoj 6271. 2019.8.4【NOIP提高组A】锻造 (forging)
    jzoj 6273. 2019.8.4【NOIP提高组A】欠钱 (money)
    jzoj 6272. 2019.8.4【NOIP提高组A】整除 (division)
    2019.08.04【NOIP提高组】模拟 A 组 总结
    jzoj 2184. 羊羊列队
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9820117.html
Copyright © 2011-2022 走看看