解题思路

这是一个动态规划问题。通过计算每个可能的石头数量组合来统计方案数。

关键点:

  1. 只需考虑较小值到较大值的范围
  2. 使用动态规划数组记录方案数
  3. 每层需要的石头数逐渐增加
  4. 结果需要对1000000007取模

算法步骤:

  1. 处理特殊情况(一种颜色为0)
  2. 确保 是较小值
  3. 动态规划计算每种组合的方案数

代码

#include <bits/stdc++.h>
using namespace std;

class Solution {
private:
    static const int MOD = 1000000007;
    
public:
    int buildTower(int red, int green) {
        // Handle special case
        if (red == 0 || green == 0) {
            return 1;
        }
        
        // Make sure red is smaller
        if (red > green) {
            swap(red, green);
        }
        
        vector<int> dp(300001, 0);
        dp[0] = dp[1] = 1;
        
        int currentSum = 1;
        int left = 0, right = 0;
        
        // Calculate maximum possible levels
        for (int level = 2; level <= sqrt(2 * (red + green)); level++) {
            currentSum += level;
            
            // Calculate valid range
            int maxStones = min(currentSum, red);
            int minStones = max(currentSum - green, 0);
            
            if (minStones > maxStones) {
                break;
            }
            
            right = maxStones;
            left = minStones;
            
            // Update dp array
            for (int stones = right; stones >= level + 1; stones--) {
                dp[stones] = (dp[stones] + dp[stones - level]) % MOD;
            }
            dp[level]++;
        }
        
        // Calculate final result
        int result = 0;
        for (int i = left; i <= right; i++) {
            result = (result + dp[i]) % MOD;
        }
        
        return result;
    }
};

int main() {
    int red, green;
    cin >> red >> green;
    
    Solution solution;
    cout << solution.buildTower(red, green) << endl;
    
    return 0;
}
import java.util.*;

public class Main {
    static class Solution {
        private static final int MOD = 1000000007;
        
        public int buildTower(int red, int green) {
            // 特殊情况处理
            if (red == 0 || green == 0) {
                return 1;
            }
            
            // 确保red是较小值
            if (red > green) {
                int temp = red;
                red = green;
                green = temp;
            }
            
            int[] dp = new int[300001];
            dp[0] = dp[1] = 1;
            
            int currentSum = 1;
            int left = 0, right = 0;
            
            // 计算最大可能层数
            for (int level = 2; level <= Math.sqrt(2 * (red + green)); level++) {
                currentSum += level;
                
                // 计算有效范围
                int maxStones = Math.min(currentSum, red);
                int minStones = Math.max(currentSum - green, 0);
                
                if (minStones > maxStones) {
                    break;
                }
                
                right = maxStones;
                left = minStones;
                
                // 更新dp数组
                for (int stones = right; stones >= level + 1; stones--) {
                    dp[stones] = (dp[stones] + dp[stones - level]) % MOD;
                }
                dp[level]++;
            }
            
            // 计算最终结果
            int result = 0;
            for (int i = left; i <= right; i++) {
                result = (result + dp[i]) % MOD;
            }
            
            return result;
        }
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int red = sc.nextInt();
        int green = sc.nextInt();
        
        Solution solution = new Solution();
        System.out.println(solution.buildTower(red, green));
        
        sc.close();
    }
}
class Solution:
    def buildTower(self, red, green):
        MOD = 1000000007
        
        # Handle special case
        if red == 0 or green == 0:
            return 1
            
        # Make sure red is smaller
        if red > green:
            red, green = green, red
            
        dp = [0] * 300001
        dp[0] = dp[1] = 1
        
        current_sum = 1
        left = right = 0
        
        # Calculate maximum possible levels
        for level in range(2, int((2 * (red + green)) ** 0.5) + 1):
            current_sum += level
            
            # Calculate valid range
            max_stones = min(current_sum, red)
            min_stones = max(current_sum - green, 0)
            
            if min_stones > max_stones:
                break
                
            right = max_stones
            left = min_stones
            
            # Update dp array
            for stones in range(right, level, -1):
                dp[stones] = (dp[stones] + dp[stones - level]) % MOD
            dp[level] += 1
            
        # Calculate final result
        result = sum(dp[left:right+1]) % MOD
        
        return result

# Read input and solve
red, green = map(int, input().split())
solution = Solution()
print(solution.buildTower(red, green))

算法及复杂度

  • 算法:动态规划
  • 时间复杂度:,其中n是石头总数
  • 空间复杂度:,用于存储dp数组