首页 > 其他分享 >概率dp

概率dp

时间:2023-01-16 22:23:24浏览次数:33  
标签:GCC 概率 int mask ++ dp

  • https://codeforces.com/contest/678/problem/E

思路:

  • 这个概率dp正着方向来算很麻烦,因为可以改变这个选手比赛的顺序(假设擅长的次序为p0,p1,p2,p3,...,pn)
  • 定义f[mask][i]为在mask状态下,赢家是i,mask在二进制上1表示已经上过场或者正在场上,0表示还未上过场
  • 状态转移:从终点f[1][0] = 1出发(因为要计算的概率是在让1号胜利的最大可能性上的),推导f[(1<<n)-1][0~n-1]中的最大值就是答案
  • 具体计算可以从2开始枚举mask,每次找到任意两个在擂台上的人,加上两个人互相击败的,但是赢家不变的情况
  • 此题难度较高,思维和代码能力缺一不可

#include<bits/stdc++.h>
#define debug1(a) cout<<#a<<'='<< a << endl;
#define debug2(a,b) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<endl;
#define debug3(a,b,c) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<endl;
#define debug4(a,b,c,d) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<"  "<<#d<<" = "<<d<<endl;
#define debug5(a,b,c,d,e) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<"  "<<#d<<" = "<<d<<"  "<<#e<<" = "<<e<<endl;
#define endl "\n"
#define fi first
#define se second

#define int long long

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;

//#pragma GCC optimize(3,"Ofast","inline")
//#pragma GCC optimize(2)
const int N = 20;
double a[N][N];
double f[1<<N][N];//f[i][j]表示状态为i(0上过擂台后已死亡,1表示存活)的情况下,j是当前状态的赢家(j+1)


void solve()
{
    int n;cin >> n;
    for(int i = 0;i < n;i ++)
    {
        for(int j = 0;j < n;j ++)
        {
            cin >> a[i][j];
        }
    }

    f[1][0] = 1;//最后的结果,逆推回初始状态max(f[(1<<n)-1][j]),全部存活,且第一个上场的人
    for(int mask = 2;mask < 1 << n; mask ++)
    {
        for(int i = 0;i < n;i ++)if(mask >> i & 1)
        {
            for(int j = 0;j < n;j ++)if(j != i && (mask >> j & 1))
            {
                f[mask][i] = max(f[mask][i],f[mask ^ (1<<i)][j] * a[j][i] + f[mask^(1<<j)][i] * a[i][j]);
            }
            
        }
    }
    double ans = 0;
    for(int i = 0;i < n;i ++)
    {
        ans = max(ans,f[(1<<n)-1][i]);
    }
    printf("%.7lf",ans);
}

signed main()
{
    /*
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    */
    int T = 1;//cin >> T;

    while(T--){
        //puts(solve()?"YES":"NO");
        solve();
    }
    return 0;

}
/*

*/

 

标签:GCC,概率,int,mask,++,dp
From: https://www.cnblogs.com/cfddfc/p/17056428.html

相关文章