关于CSU 1725以及CodeForce 148D自己的解法


                 老实说那几天自己还不会概率DP,就按照自己的野路子来了。。但是发现也还是能够做出来,时间也和别人的差不多。。

                 感觉忘记太可惜了,于是特此记录下来。

                 数据结构:队列

                 例题:CSU 1725

                 我一开始的想法是用一个五维数组来表示,double arr[a][b][c][d][e] ,a表示余剩攻击次数,b表示余剩血量,c,d,e分别表示余剩的1,2,3血的奴隶主,而                   arr[a][b][c][d][e]储存的是发生这个局面的概率。

                 由一个局面到达另外一个局面的情况只有5种,攻击英雄致死,攻击英雄未致死,攻击一血奴隶主,攻击二血奴隶主并产生一个新的,攻击二血奴隶主

            未产生新的,攻击三血的情况同攻击二血的。

                因此,我采用一个结构体Node,Node有5个数据成员,含义同五维数组的下标,当首先把最初的局面加入队列,然后通过不断的取队列的front来不断推演,停止演算的条件是英雄血量为0或者是余剩次数为0

            接下来发生的局面,并且同时更新arr五维数组,也就是说,最终在五维数组里面储存的是各个局面发生的概率,我只需要把这个五维数组遍历一遍,取出我想要的局面的  概率,都加起来即可。

           PS:flag数组的含义和SPFA里面的一个bool数组差不多,用于表示某一个局面是否已经在队列中存在。

           代码:(在所有AC的人里面,我的代码是最长的。。。。。)

         

#include<iostream>
#include<queue>
#include<cstring>

using namespace std;

int t,x,y,z,num;
struct Node{
    int times,health,num1,num2,num3;
    Node(int e=0,int a=0,int b=0,int c=0,int d=0):times(e),health(a),num1(b),num2(c),num3(d){};
}te;

queue<Node> q;

double arr[25][25][8][8][8],probaboly;
bool flag[25][25][8][8][8];

int main(){
    ios_base::sync_with_stdio(false);
    cout.setf(ios_base::fixed);
    cout.precision(6);
    cin>>t;
    while(t--){
        cin>>x>>y>>z;
        if(x<y)
            cout<<"0.000000\n";
        else{
            arr[x][y][0][0][z]=1;q.push({x,y,0,0,z});
            flag[x][y][0][0][z]=true;
            while(!q.empty()){
                te=q.front();q.pop();flag[te.times][te.health][te.num1][te.num2][te.num3]=false;
                //cout<<te.times<<' '<<te.health<<' '<<te.num1<<' '<<te.num2<<' '<<te.num3<<endl;
                if(te.health==0)
                    continue;
                if(te.times!=0){
                num=1+te.num1+te.num2+te.num3;

                if(te.health!=0){
                arr[te.times-1][te.health-1][te.num1][te.num2][te.num3]+=arr[te.times][te.health][te.num1][te.num2][te.num3]/num;
                if(!flag[te.times-1][te.health-1][te.num1][te.num2][te.num3])
                q.push({te.times-1,te.health-1,te.num1,te.num2,te.num3}),flag[te.times-1][te.health-1][te.num1][te.num2][te.num3]=true;
                }

                if(te.num1!=0){
                    arr[te.times-1][te.health][te.num1-1][te.num2][te.num3]+=arr[te.times][te.health][te.num1][te.num2][te.num3]*te.num1/num;
                    if(!flag[te.times-1][te.health][te.num1-1][te.num2][te.num3])
                    q.push({te.times-1,te.health,te.num1-1,te.num2,te.num3}),flag[te.times-1][te.health][te.num1-1][te.num2][te.num3]=true;
                }

                if(te.num2!=0){
                    if(num<8){
                    arr[te.times-1][te.health][te.num1+1][te.num2-1][te.num3+1]+=arr[te.times][te.health][te.num1][te.num2][te.num3]*te.num2/num;
                    if(!flag[te.times-1][te.health][te.num1+1][te.num2-1][te.num3+1])
                    q.push({te.times-1,te.health,te.num1+1,te.num2-1,te.num3+1}),flag[te.times-1][te.health][te.num1+1][te.num2-1][te.num3+1]=true;
                    }
                    else{
                        arr[te.times-1][te.health][te.num1+1][te.num2-1][te.num3]+=arr[te.times][te.health][te.num1][te.num2][te.num3]*te.num2/num;
                        if(!flag[te.times-1][te.health][te.num1+1][te.num2-1][te.num3])
                        q.push({te.times-1,te.health,te.num1+1,te.num2-1,te.num3}),flag[te.times-1][te.health][te.num1+1][te.num2-1][te.num3]=true;
                    }
                }
                if(te.num3!=0){
                    if(num<8){
                    arr[te.times-1][te.health][te.num1][te.num2+1][te.num3]+=arr[te.times][te.health][te.num1][te.num2][te.num3]*te.num3/num;
                    if(!flag[te.times-1][te.health][te.num1][te.num2+1][te.num3])
                    q.push({te.times-1,te.health,te.num1,te.num2+1,te.num3}),flag[te.times-1][te.health][te.num1][te.num2+1][te.num3]=true;
                    }
                    else{
                        arr[te.times-1][te.health][te.num1][te.num2+1][te.num3-1]+=arr[te.times][te.health][te.num1][te.num2][te.num3]*te.num3/num;
                        if(!flag[te.times-1][te.health][te.num1][te.num2+1][te.num3-1])
                        q.push({te.times-1,te.health,te.num1,te.num2+1,te.num3-1}),flag[te.times-1][te.health][te.num1][te.num2+1][te.num3-1]=true;
                    }
                }
                }
            }
            for(int m=x-y;m>=0;--m)
            for(int i=0;i<=7;++i)
            for(int j=0;j<=7-i;++j)
            for(int k=0;k<=7-i-j;++k)
            probaboly+=arr[m][0][i][j][k];//,cout<<m<<' '<<i<<' '<<j<<' '<<k<<' '<<arr[m][0][i][j][k]<<endl;

            //cout<<arr[0][0][0][0][1]<<' '<<arr[0][0][0][1][1]<<endl;
            cout<<probaboly<<endl;memset(arr,0,sizeof(arr));probaboly=0;//memset(flag,0,sizeof(flag));
        }
    }
    return 0;
}

         CodeForce 148D:原来是是一个龙和公主抓老鼠的故事,这种事情当然是要公主赢才是。。而且公主的意见也很不错呀。。龙为什么就不听话呢。。。
         扯远了。。咳咳,下面是正题
         同样的,使用一个结构体来表示到达这个局面的概率,然后数组更新完毕之后,回过头去,在每一种状态的下算一遍公主胜利的概率。
         至于局面终止的情况,就是没有白色的老鼠了
        
#include<cstdio>
#include<queue>
#include<cstring>

using namespace std;

int w,b;
double arr[1010][1010],sum;
struct Node{
    int w,b;
    Node(int a =0,int c=0):w(a),b(c){};
}te;
bool flag[1010][1010];

queue<Node> q;

int main(){
    while(scanf("%d",&w)!=EOF){
        scanf("%d",&b);
        arr[w][b]=1;q.push({w,b});
        while(!q.empty()){
            te=q.front();q.pop();flag[te.w][te.b]=false;
            if(te.w&&!te.b)continue;
            if(te.w>0&&te.b>1){
                arr[te.w-1][te.b-2]+=arr[te.w][te.b]*te.b/(te.b+te.w)*(te.b-1)/(te.b+te.w-1)*te.w/(te.b+te.w-2);
                if(!flag[te.w-1][te.b-2])
                q.push({te.w-1,te.b-2}),flag[te.w-1][te.b-2]=true;
            }
            if(te.b>2){
                    //printf("%lf %lf ",arr[te.w][te.b-3],arr[te.w][te.b]*te.b/(te.w+te.b)*(te.b-1)/(te.b+te.w-1)*(te.b-2)/(te.b+te.w-2));
                arr[te.w][te.b-3]+=arr[te.w][te.b]*te.b/(te.w+te.b)*(te.b-1)/(te.b+te.w-1)*(te.b-2)/(te.b+te.w-2);
            //printf("%lf",arr[1][0]);
                if(!flag[te.w][te.b-3])
                q.push({te.w,te.b-3}),flag[te.w][te.b-3]=true;
            }

        }

        for(int i=1;i<=w;++i){
        for(int j=0;j<=b;++j)
        sum+=arr[i][j]*i/(i+j);//,printf("%lf %d %d ",arr[i][j],i,j);
        }
        printf("%.9lf\n",sum);sum=0;memset(arr,0,sizeof(arr));
    }
}

         以上,自己的野套路讲解完毕


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看rEADME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看rEADME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值