結果
| 問題 |
No.766 金魚すくい
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 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()
qwewe