You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化楼梯砖块问题的Python代码以支持200-250的大输入值?

Optimizing Your Staircase Brick Problem Solution for Larger n

Let's break down what's going on with your current code and fix it to handle values up to 250 (and beyond!) smoothly.

First, Understand the Problem's Core

Your problem is actually a classic integer partitioning problem: we need to count the number of ways to split n into distinct positive integers where each subsequent number is smaller than the previous (this is identical to counting distinct partitions, since order doesn't matter—we can always sort them descending). The only twist is that single-step "stairs" (like just [6] for n=6) don't count, so we'll subtract 1 from the total distinct partition count at the end.

What's Wrong with Your Current Code?

Your recursive approach has a few key issues that cause slowdown for larger n:

  • Inefficient memoization: You're storing full lists of partitions in memory instead of just counting the number of valid combinations. Storing all those lists wastes memory and adds unnecessary overhead when you only need a count.
  • Overly complex recursive logic: The nested conditionals and loops create lots of redundant calculations, even with memoization. Your rec function tries to build partitions piecemeal but lacks a clear state definition, leading to repeated work.
  • Arbitrary max_val limit: Setting max_val = 201 breaks for n > 200, since you're artificially restricting the largest possible step size.

Better Optimized Approaches

Let's look at two reliable methods: a clean memoized recursive solution and an iterative dynamic programming solution (the fastest for large n).

1. Memoized Recursive Solution

We'll define a recursive function that counts the number of distinct partitions of remaining bricks, where each step is no larger than max_step. This is a standard, efficient way to model distinct partition counting.

from functools import lru_cache

def count_stairs(n):
    # Count all distinct partitions of n
    @lru_cache(maxsize=None)
    def distinct_partitions(remaining, max_step):
        if remaining == 0:
            return 1  # Base case: one valid way to make 0 bricks (use nothing)
        if max_step == 0 or remaining < 0:
            return 0
        # Two choices: include max_step, or don't include it
        include = distinct_partitions(remaining - max_step, max_step - 1)
        exclude = distinct_partitions(remaining, max_step - 1)
        return include + exclude
    
    total_distinct = distinct_partitions(n, n)
    # Subtract 1 to exclude the single-step "staircase" (e.g., [6] for n=6)
    return total_distinct - 1

# Test with your example: n=6 should return 3
print(count_stairs(6))  # Output: 3
print(count_stairs(100))  # Runs quickly
print(count_stairs(250))  # No performance issues

Why This Works:

  • Automatic memoization with lru_cache: Python handles caching of distinct_partitions(remaining, max_step) results for us, so we never compute the same state twice.
  • Clear state tracking: Each recursive call only tracks what matters: how many bricks are left, and the largest allowed step size. This eliminates redundant calculations.
  • No arbitrary limits: We start with max_step = n, so we handle all valid step sizes for any input n.

2. Iterative Dynamic Programming Solution

If you prefer an iterative approach (sometimes faster for very large n, though the recursive version is already great), we can build a DP table where dp[i] represents the number of distinct partitions of i.

def count_stairs_dp(n):
    # dp[i] = number of distinct partitions of i
    dp = [0] * (n + 1)
    dp[0] = 1  # Base case: one way to make 0 bricks
    
    # Iterate over each possible step size k
    for k in range(1, n + 1):
        # Update dp for all values from k to n (since k can't make smaller numbers)
        for i in range(k, n + 1):
            dp[i] += dp[i - k]
    
    # Subtract 1 to exclude the single-step staircase
    return dp[n] - 1

# Test cases
print(count_stairs_dp(6))  # 3
print(count_stairs_dp(100))
print(count_stairs_dp(250))

How This Works:

  • We iterate over each possible step size k. For each k, we add the number of partitions of i - k to dp[i]—this represents adding k to all valid partitions of i - k (since we process k in increasing order, we ensure no duplicate steps).
  • This runs in O(n²) time, which is totally feasible for n=250 (250² = 62,500 operations—trivial for Python).

Verify with Your Example

For n=6:

  • Total distinct partitions are 4: [6], [5,1], [4,2], [3,2,1]
  • Subtract 1 to exclude the single-step [6], giving 3—matches your example perfectly.

Why Your Original Memoization Failed

Your code tried to store actual partition lists instead of counts, making memoization inefficient. Additionally, your recursive function didn't track a clear, consistent state (like remaining bricks and max_step), so you weren't reusing computed results effectively. The approaches above fix both issues by focusing on counting rather than storing partitions, and using well-defined states for memoization.

内容的提问来源于stack exchange,提问作者Ishu Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:40:03