結果
| 問題 |
No.1001 注文の多い順列
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-07-02 15:26:54 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 224 ms / 2,000 ms |
| コード長 | 1,552 bytes |
| コンパイル時間 | 191 ms |
| コンパイル使用メモリ | 82,348 KB |
| 実行使用メモリ | 77,800 KB |
| 最終ジャッジ日時 | 2024-06-29 01:34:59 |
| 合計ジャッジ時間 | 4,702 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 31 |
ソースコード
def main1(n,tx_):
mod=10**9+7
tx=[[t,x] if t==0 else [t,x-1] for t,x in tx_]
tx.sort(key=lambda x:x[1])
# dp[k]:以上条件をすくなくともk個満たさない。
dp=[0]*(n+1)
dp[0]=1
num0,num1=0,0
for i,(t,x) in enumerate(tx):
ndp=[0]*(n+1)
if t==0:
# 以下条件
if x<=num0:return 0
for j in range(n):
# 以上条件を少なくともj個満たさない状態の遷移
# 今まで出てきた以上条件の内j個は少なくとも満たしていない。pk<=xkとなる箇所があった。
ndp[j]+=dp[j]*(x-num0-j)
ndp[j]%=mod
num0+=1
else:
# 以上条件
for j in range(n):
if dp[j]==0:break
# 以上条件を少なくともj個満たさない状態の遷移
# x+1以上を入れると以上条件を満たせる。
# x以下を入れる。
if j+1<n:
ndp[j+1]+=dp[j]*max(0,(x-num0-j))
ndp[j+1]%=mod
# 後回し
ndp[j]+=dp[j]
ndp[j]%=mod
num1+=1
dp=ndp
kai=[1,1]
for i in range(2,n+1):kai.append(kai[-1]*i%mod)
for k in range(num1+1):
# dp[k]:k個満たしていないことが確定している。のこりnum1-k個は好きに入れられる。
dp[k]*=kai[num1-k]
dp[k]%=mod
ans=dp[0]
for k in range(1,n+1):
if k%2==0:
ans+=dp[k]
else:
ans-=dp[k]
ans%=mod
return ans
if __name__=='__main__':
n=int(input())
tx=[list(map(int,input().split())) for _ in range(n)]
ret1=main1(n,tx)
print(ret1)