1. 程式人生 > >LightOJ - 1151概率dp+高斯消元

LightOJ - 1151概率dp+高斯消元

include 得到 ofa 期望 cas efi cos size com

概率dp+高斯消元

https://vjudge.net/problem/LightOJ-1151

題意:剛開始在1,要走到100,每次走的距離1-6,超過100重來,有一些點可能有傳送點,可以傳送到前面或後面,那麽概率dp沒法遞推,只能高斯消元

設期望E(x),首先100這個位置的期望E(100)=0,然後可以找出方程, 對於傳送點,E(x)=E(go(x)),對於非傳送點,E(x)=(E(x+1)+E(x+2)+E(x+3)+E(x+4)+E(x+5)+E(x+6)+6)/cnt(cnt是可轉移的點數)

對於大於100的E肯定是0,不用考慮進來,然後高斯消元就得到了結果

技術分享圖片
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define
ll long long #define vi vector<int> #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pli pair<ll,int> #define pii pair<int,int> #define cd complex<double> #define ull unsigned long long #define
base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-8; const int N=100+10,maxn=100000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; double a[N][N],ans[N]; void gauss(int n) { for(int i=1;i<n;i++) { if(a[i][i]==0) { int id=0; for(int j=i+1;j<=n;j++) if(a[j][i]!=0) id=j; for(int j=i;j<=n+1;j++) swap(a[i][j],a[id][j]); } for(int j=i+1;j<=n;j++) { double t=a[j][i]/a[i][i]; for(int k=i;k<=n+1;k++) a[j][k]-=(a[i][k]*t); } } // for(int i=1;i<=n;i++) // { // for(int j=1;j<=n+1;j++) // printf("%.12f ",a[i][j]); // puts(""); // } for(int i=n;i>=1;i--) { for(int j=i+1;j<=n;j++) a[i][n+1]-=ans[j]*a[i][j]; ans[i]=a[i][n+1]/a[i][i]; } } int go[N]; int main() { int T,cnt=0;scanf("%d",&T); while(T--) { int n;scanf("%d",&n); memset(go,0,sizeof go); for(int i=0;i<n;i++) { int a,b; scanf("%d%d",&a,&b); go[a]=b; } // puts("++"); memset(a,0,sizeof a); for(int i=1;i<=93;i++) { if(go[i]) { a[i][i]=1; a[i][go[i]]=-1; } else { a[i][i]=6.0; for(int j=i+1;j<=i+6;j++)a[i][j]=-1.0; a[i][101]=6; } } for(int i=94;i<=99;i++) { if(go[i]) { a[i][i]=1; a[i][go[i]]=-1; } else { a[i][i]=1.0*(100-i); for(int j=i+1;j<=100;j++)a[i][j]=-1.0; a[i][101]=6; } } a[100][100]=1.0; gauss(100); printf("Case %d: %.12f\n",++cnt,ans[1]); } return 0; } /*********************** ***********************/
View Code

LightOJ - 1151概率dp+高斯消元