柱爷与远古法阵(高斯消元+概率期望)

题目:click
貌似不能交啊。在这里插入图片描述逆推期望,dp[x]=(dp[x+1]+dp[x+2]+…+dp[x+6])/6+1,n个方程n个未知数,dp[u]==dp[v](u , v可以转换的时候),当x+i>n时,dp[x+i]并不能转移到dp[x],x的系数自减1,次数仍然计算,右侧常数6不变,高斯消元去解。
最后不知道为什么要强制转换为double才有答案。(能交的时候在交一发)

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 50005*4
using namespace std;
typedef long long ll;
const int MAXN=262144 * 2+ 10;
const double PI=acos(-1.0);
const long double eps=1e-14;
long double a[310][310];
int f[310];
int main()
{
    memset(a,0,sizeof(a));
    memset(f,0,sizeof(f));
    int n,m,i,j;
    scanf("%d %d",&n,&m);
    for(i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        f[x]=y;
    }
    for(i=1;i<n;i++)
    {
        a[i][i]=6.0;
        if(f[i])
        {
            a[i][f[i]]=-6.0;
            a[i][n+1]=0;
            continue;
        }
        a[i][n+1]=6.0;
        for(j=1;j<=6;j++)
        {
            if(i+j<=n)
            {
                a[i][i+j]=-1.0;
            }
            else
                {
                    a[i][i]-=1.0;
                }
        }
    }
    a[n][n]=1.0;
    a[n][n+1]=0.0;
    for(i=1;i<n;i++)//矩阵计算
    {
        int temp=i;
        for(j=i+1;j<=n;j++)
        {
            if(fabs(a[j][i])>eps)
            {
                temp=j;
            }
        }
        if(fabs(a[temp][i])>eps)
        {
            for(j=1;j<=n+1;j++)
                swap(a[i][j],a[temp][j]);
            for(j=i+1;j<=n;j++)
            {
                if(fabs(a[j][i])>eps)
                {
                    long double tmp=a[j][i]/a[i][i];
                    for(int k=i;k<=n+1;k++)
                    {
                        a[j][k]-=tmp*a[i][k];
                    }
                }
            }
        }
    }
    for(i=n;i>=1;i--)//回代结果
    {
        for(j=i+1;j<=n;j++)
        {
            if(fabs(a[i][j])>eps)
            {
                a[i][n+1]-=a[i][j]*a[j][n+1];
            }
        }
        if(abs(a[i][i])<=eps&&abs(a[i][n+1])>eps)//方程左式子为0 右式大于0的情况无解题目说了存在
        {
            printf("-1\n");
            return 0;
        }
        a[i][n+1]/=a[i][i];
    }
    printf("%.12lf",(double)a[1][n+1]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43958964/article/details/106207574