Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions 1359.Count-All-Valid-Pickup-and-Delivery-Options/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 1359. Count All Valid Pickup and Delivery Options

## step1
算数だと思って解いた。9mほど。

modulo定数はSolution固有だと考えてクラス内に定義する。グローバル変数にしても良いと思う。

バックトラックがキーワードにあるので書くがTLEした。他の書き方があるのか?

## 他の解法
https://leetcode.com/problems/count-all-valid-pickup-and-delivery-options/solutions/4024280/9957-dp-math-recursion-by-vanamsen-qd4r/

再帰と直接計算する方法

https://docs.python.org/ja/3/library/functions.html#pow

> If mod is present and exp is negative, base must be relatively prime to mod. In that case, pow(inv_base, -exp, mod) is returned, where inv_base is an inverse to base modulo mod.

逆元の計算をpowで行える

https://leetcode.com/problems/count-all-valid-pickup-and-delivery-options/solutions/3223439/2-python-solutions-with-explanation-using-dp-and-backtracking/

バックトラックはほとんど自分と同じ解法なので、TLEを避ける方法はなさそう?

https://discord.com/channels/1084280443945353267/1196498607977799853/1358454829005144125

> Count All Valid Pickup and Delivery Options ... Math・Dynamic Programming・Combinatorics に分類される問題に、ソフトウェアエンジニアとしての教育効果がどれくらいあるのか分かりませんでした。最近の入社試験で出題されるということであり、かつ入社試験に向けた練習をするのであれば、入れたほうがよいと思います。

## step3
省略
11 changes: 11 additions & 0 deletions 1359.Count-All-Valid-Pickup-and-Delivery-Options/step1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Solution:
MODULO = 10 ** 9 + 7
def countOrders(self, n: int) -> int:
count = 1
for i in range(n):
num_order = i * 2
num_insertion = (num_order + 1) * (num_order + 2) // 2 # 1 + 2 + ... (num_order + 1)
count *= num_insertion % self.MODULO
count %= self.MODULO

return count
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from enum import IntEnum

class OrderStatus(IntEnum):
WAITING = 0
PICKED_UP = 1
DELIVERED = 2

class Solution:
MODULO = 10 ** 9 + 7
def countOrders(self, n: int) -> int:
order_statuses = [OrderStatus.WAITING] * n
count = 0

def update_order_status(i):
nonlocal count
if i == 2 * n:
count += 1
count %= self.MODULO
return

for j in range(n):
if order_statuses[j] == OrderStatus.DELIVERED:
continue

if order_statuses[j] == OrderStatus.WAITING:
order_statuses[j] = OrderStatus.PICKED_UP
update_order_status(i + 1)
order_statuses[j] = OrderStatus.WAITING
continue

order_statuses[j] = OrderStatus.DELIVERED
update_order_status(i + 1)
order_statuses[j] = OrderStatus.PICKED_UP

update_order_status(0)
return count
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import math

class Solution:
MODULO = 10 ** 9 + 7
def countOrders(self, n: int) -> int:
numerator = math.factorial(2 * n) % self.MODULO
denominator = pow(2, n, self.MODULO)
return numerator * pow(denominator, -1, self.MODULO) % self.MODULO
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import functools
class Solution:
MODULO = 10 ** 9 + 7
def countOrders(self, n: int) -> int:

@functools.cache
def count_orders_helper(n):
if n == 1:
return 1

count = (self.countOrders(n - 1) * (2 * n - 1) * n) % self.MODULO
return count

return count_orders_helper(n)