結果
問題 |
No.766 金魚すくい
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:15:40 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,808 bytes |
コンパイル時間 | 300 ms |
コンパイル使用メモリ | 82,180 KB |
実行使用メモリ | 268,208 KB |
最終ジャッジ日時 | 2025-05-14 13:17:14 |
合計ジャッジ時間 | 7,308 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 20 TLE * 1 -- * 21 |
ソースコード
import sys # Set higher recursion depth for safety, although this DP is iterative # sys.setrecursionlimit(2000) # Use fast I/O input = sys.stdin.readline def solve(): # Read input N: number of goldfish, M: number of poi, P: probability percent of breaking N, M, P_percent = map(int, input().split()) # Read goldfish values V = list(map(int, input().split())) # Define modulus MOD = 10**9 + 7 # Handle edge case P=0: # If P=0, probability of breaking is 0. Poi never breaks. # We can scoop all N goldfish as long as we have at least one poi (M >= 1 constraint is given). # The stopping condition "all M poi break" is never met. # The process stops when "all N goldfish are scooped". # The total expected value is simply the sum of all goldfish values. if P_percent == 0: total_value = 0 for x in V: total_value = (total_value + x) % MOD print(total_value) return # Handle edge case P=100: # If P=100, probability of breaking is 100%. Any attempt breaks the poi. # We never succeed in scooping any fish. # The total expected value is 0. if P_percent == 100: print(0) return # Calculate modular inverse of 100 to compute probabilities p and q # Using Fermat's Little Theorem: a^(MOD-2) mod MOD is the inverse of a mod MOD for prime MOD. inv100 = pow(100, MOD - 2, MOD) # Calculate probability p (poi breaks) and q (scoop succeeds) p = (P_percent * inv100) % MOD # Calculate q = 1 - p. Add MOD to handle potential negative result before taking modulo. q = (1 - p + MOD) % MOD # Sort goldfish values in descending order. The optimal strategy is greedy: # always attempt to scoop the available goldfish with the highest value. V.sort(reverse=True) # Initialize DP state array. # E_next[l] will store the expected value E(i+1, l), which means: # we have considered fish 1 to i, and l poi have broken. We are about to consider fish i+1. # Initially, represents E(N+1, l) = 0 for all l, as there are no more fish after N. E_next = [0] * (M + 1) # Precompute powers of p modulo MOD, needed for DP calculation. # p_powers[k] = p^k mod MOD p_powers = [1] * (M + 1) for k in range(1, M + 1): p_powers[k] = (p_powers[k-1] * p) % MOD # DP calculation main loop # We iterate backwards from the last fish (index N-1) down to the first fish (index 0). # This corresponds to calculating E(i, l) based on values E(i+1, *). # E_curr[l] stores E(i, l) for the current fish i. E_curr = [0] * (M + 1) # S_curr[l] is a helper array to compute the summation term efficiently. # S(i, l) = sum_{j=0}^{M-l-1} p^j * E(i+1, l+j) S_curr = [0] * (M + 1) # Loop through fish i from N down to 1 (0-indexed: N-1 down to 0) for i in range(N - 1, -1, -1): # Get the value of the current fish being considered Vi = V[i] # Compute helper array S_curr for current fish i, using E_next which holds values for E(i+1, *) # The recurrence relation for S is S(i, l) = E(i+1, l) + p * S(i, l+1). # We compute this backwards from l = M-1 down to 0. # Base case for the recurrence S(i, M) = 0 S_curr[M] = 0 for l in range(M - 1, -1, -1): # Calculate S_curr[l] using the value E_next[l] = E(i+1, l) and the previously computed S_curr[l+1]. S_curr[l] = (E_next[l] + p * S_curr[l+1]) % MOD # Compute E_curr[l] = E(i, l) using the formula: # E(i, l) = Vi * (1 - p^{M-l}) + q * S(i, l) # Iterate l from 0 to M-1. for l in range(M): # Calculate (1 - p^{M-l}) mod MOD safely. Add MOD before taking modulo to handle potential negative result. one_minus_p_pow = (1 - p_powers[M-l] + MOD) % MOD # Calculate the first term: Vi * (1 - p^{M-l}) term1 = (Vi * one_minus_p_pow) % MOD # Calculate the second term: q * S(i, l) term2 = (q * S_curr[l]) % MOD # Combine the two terms E_curr[l] = (term1 + term2) % MOD # Base case for E: E(i, M) = 0 because if M poi are broken, we cannot scoop anymore. E_curr[M] = 0 # Prepare E_next for the next iteration (which will consider fish i-1). # E_next should hold the values E(i, l) that we just computed in E_curr. # Using list slicing `[:]` creates a copy of E_curr. This is important. E_next = E_curr[:] # After the loop finishes, E_next holds the values E(1, l). # The final answer is E(1, 0), the expected value starting with fish 1 and 0 broken poi. print(E_next[0]) # Call the solve function to run the program solve()