-
[Baekjoon - 2144] 울타리 넘기문제 풀이/Baekjoon Online Judge 2023. 3. 1. 01:14
난이도: Gold I
태그
더보기- Dynamic Programming
- Line Intersection
풀이
0. 풀이를 읽기 전: 정의
더보기 는 번째 점의 위치를 의미합니다.- 시작점은
, 즉 번째 점으로 표현합니다.
- 시작점은
는 번째 울타리의 위치 (선분)을 나타냅니다. 는 번째 울타리의 높이를 나타냅니다.
1.
에서 로 성공적으로 이동할 수 있는 확률은?더보기어떤 울타리
와 가 교차한다면, 이 울타리를 뛰어넘을 확률은 가 됩니다.그러므로, 모든 울타리를 보면서
와 가 교차한다면, 확률에 를 곱해주면 됩니다.이 문제에서는 세 점이 한 직선 위에 놓이는 경우는 교차하지 않음으로 판정하면
의 확률로 뛰어넘는다 를 잘 처리할 수 있습니다.이러한 확률을
시간에 계산해둔 뒤, 라고 부릅시다.단, 계산의 편의를 위해
으로 두는 것을 추천합니다.2. 그렇다면,
번 이동해서 로 이동할 수 있는 확률은?더보기 = 번 이동해서 로 이동할 수 있는 확률 을 정의해봅시다.초항은,
번 이동했을 때 , 입니다.점화식은,
번 이동해서 로 온 뒤, 의 이동을 하는 것을 생각해보면 가 됩니다.주의할 점은, 점화식 계산 중에는
번 점으로 돌아가면 안 됩니다!3. 문제의 답은?
더보기 번의 이동을 한 뒤, 다시 시작점으로 돌아와야 계산이 끝나겠죠.이는,
까지 계산을 끝낸 뒤에, 의 이동까지 처리한 값인 을 출력해주면 됩니다.4. 코드
더보기123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657int ccw(pl2 p1, pl2 p2, pl2 p3){ll a = p1.sc*p2.fr + p2.sc*p3.fr + p3.sc*p1.fr;ll b = p1.sc*p3.fr + p3.sc*p2.fr + p2.sc*p1.fr;return sgn(a-b);}bool crs(pl4 l1, pl4 l2){pl2 p1 = l1.fr, p2 = l1.sc;pl2 p3 = l2.fr, p4 = l2.sc;int r123 = ccw(p1, p2, p3), r124 = ccw(p1, p2, p4);int r341 = ccw(p3, p4, p1), r342 = ccw(p3, p4, p2);if (r123 == 0 || r124 == 0 || r341 == 0 || r342 == 0){ return 0; }if (r123 != r124 && r341 != r342){ return 1; }return 0;}pl2 arr[120]; pl5 brr[220];ld adj[120][120];ld dp[520][120];void Main(){int n, m, k; pl2 p; cin >> n >> k >> m >> arr[0].fr >> arr[0].sc;for (int i = 1; i <= n; i++){ cin >> arr[i].fr >> arr[i].sc; }for (int i = 1; i <= m; i++){cin >> brr[i].fr.fr.fr >> brr[i].fr.fr.sc>> brr[i].fr.sc.fr >> brr[i].fr.sc.sc >> brr[i].sc;}for (int i1 = 0; i1 <= n; i1++){for (int i2 = 0; i2 <= n; i2++){adj[i1][i2] = 1;if (i1 == i2){ adj[i1][i2] = 0; continue; }if (i1 > i2){ adj[i1][i2] = adj[i2][i1]; continue; }for (int j = 1; j <= m; j++){if (crs({arr[i1], arr[i2]}, brr[j].fr)){ adj[i1][i2] *= (ld)1/brr[j].sc; }}}}/*for (int i1 = 0; i1 <= n; i1++){for (int i2 = 0; i2 <= n; i2++){cout << "ADJ " << i1 << ' ' << i2 << " = " << adj[i1][i2] << endl;}}*/dp[0][0] = 1;for (int i = 1; i <= k; i++){for (int p1 = 0; p1 <= n; p1++){for (int p2 = 1; p2 <= n; p2++){dp[i][p2] = max(dp[i-1][p1]*adj[p1][p2], dp[i][p2]);}}//for (int p = 1; p <= n; p++){ cout << "DP " << i << ' ' << p << " = " << dp[i][p] << endl; }}ld ans = 0;for (int p = 1; p <= n; p++){ ans = max(ans, dp[k][p]*adj[p][0]); }//for (int p = 1; p <= n; p++){ cout << "RES " << p << " = " << dp[k][p]*adj[p][0] << endl; }printf("%.4Le", ans);}cs '문제 풀이 > Baekjoon Online Judge' 카테고리의 다른 글
[Baekjoon - 15850] Random Number Generator (0) 2023.03.01 [Baekjoon - 12996] Acka (0) 2023.03.01 [Baekjoon - 9176] 메르센 합성수 (0) 2023.02.28 [Baekjoon - 14455] Don't Be Last! (0) 2023.02.23 [Baekjoon - 9613] GCD 합 (0) 2023.02.23