BZOJ 3640 JC的小蘋果

2022-05-08 03:42:12 字數 1738 閱讀 8713

我們考慮列出期望方程組,\(dp[i][j]\)表示在第\(i\)個點血量為\(j\)的時候到達\(n\)點的概率,所有的\(dp[n][j]\)都是1,所有\(j < 0\)都是0

答案是\(dp[1][hp]\)

\(dp[u][j] = \sum_ \fracdp[v][j - a[v]]\)

我們發現這個方程在j不同的時候,只有常數項發生改變,剩下的係數不變

於是我們把常數項變成乙個列向量,把需要消元的係數矩陣求乙個逆,每次計算常數項,用常數項乘逆矩陣得到每乙個血量的\(dp\)值即可

注意判自環= =

#include #define fi first

#define se second

#define pii pair#define pdi pair#define mp make_pair

#define pb push_back

#define enter putchar('\n')

#define space putchar(' ')

#define eps 1e-8

#define mo 974711

#define maxn 100005

//#define ivorysi

using namespace std;

typedef long long int64;

typedef double db;

templatevoid read(t &res)

while(c >= '0' && c <= '9')

res *= f;

}templatevoid out(t x)

if(x >= 10)

putchar('0' + x % 10);

}int n,m,hp,deg[155],blood[155];

struct node e[100005];

int sume,head[155];

db b[155],dp[155][10005],c[155];

void add(int u,int v)

struct matrix

void unit()

}friend matrix operator * (const matrix &a,const matrix &b)

}} return c;

}friend matrix operator ~(matrix a)

if(i != l)

}db t = 1.0 / a.f[i][i];

for(int j = 1 ; j <= n ; ++j)

for(int j = 1 ; j <= n ; ++j)

}} return b;

}}a;void solve()

else

}for(int u = 1 ; u <= n ; ++u)

a.f[u][u] = 1;

for(int i = head[u] ; i ; i = e[i].next)

else if(blood[v] == 0)

} }

a = ~a;

for(int i = 1 ; i <= hp ; ++i)

}} for(int u = 1 ; u <= n ; ++u)

} }

printf("%.8lf\n",dp[1][hp]);

}int main()

BZOJ3640 JC的小蘋果

建分層圖,有怪獸的點連後邊的層,每層之間是有拓撲序的所以可以一層一層高斯消元,然後我們發現每一層的方程組係數是一樣的只有常數不一樣,而常數項不影響消元過程,所以我們可以預處理消元的過程,這樣每次只需要消常數項就是n 2的,總複雜度就是hp n 2 這個 有重邊和自環,非常的蛋疼 include in...

BZOJ 3640 JC的小蘋果

題鏈 題解 期望dp,高斯消元 設dp i h 在i位置且血量為h這個狀態的期望經過次數。因為每當到達n點就停止遊戲,所以到達終點的概率就是dp n 1 dp n 2 dp n hp 可以按血量把dp分成若干個層次,我們希望這樣分層次後就可以把問題轉變為dag上的dp,可是存在傷害值為0的點,所以我...

BZOJ 3640 JC的小蘋果(逆矩陣)

題意 給出乙個無向圖,從1走到n。開始是血量h,從u到達v時血量減少a v 每次走每條路徑的概率相等。求走到n且血量大於0的概率。思路 設f h u 表示到達u血量為h的概率。由於有的點到達時不掉血,這個不好弄。列出方程組,求出每個不掉血的點由哪些點到達以及他們的係數。比如x,y,z可到達r,r點不...