【NOIP普及组】摆花

发布于:2024-11-11 ⋅ 阅读:(104) ⋅ 点赞:(0)

【NOIP普及组】摆花


💐The Begin💐点点关注,收藏不迷路💐

小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共 m 盆。通过调 查顾客的喜好,小明列出了顾客最喜欢的 n 种花,从 1 到 n 标号。为了在门口展出更多 种花,规定第 i 种花不能超过 ai 盆,摆花时同一种花放在一起,且不同种类的花需按标号 的从小到大的顺序依次摆列。试编程计算,一共有多少种不同的摆花方案。

输入

共 2 行。 第一行包含两个正整数 n 和 m,中间用一个空格隔开。 第二行有 n 个整数,每两个整数之间用一个空格隔开,依次表示 a1、a2、……an。

输出

输出只有一行,一个整数,表示有多少种方案。
注意:因为方案数可能很多,请输出方案数对 1000007 取模的结果。

样例输入

2 4
3 2

样例输出

2

提示

【输入输出样例说明】
有 2 种摆花的方案,分别是(1,1,1,2), (1,1,2,2)。括号里的 1 和 2 表示两种 花, 比如第一个方案是前三个位置摆第一种花,第四个位置摆第二种花。
【数据范围】 对于 20%数据,有 0

C语言代码

#include <stdio.h>
#include <stdlib.h>

#define MOD 1000007

int main() {
    int numFlowerTypes, totalFlowers;  // 花的种类数和总花盆数
    scanf("%d %d", &numFlowerTypes, &totalFlowers);

    int *flowerLimits = (int *)malloc((numFlowerTypes + 1) * sizeof(int));  // 存储每种花的数量限制
    for (int i = 1; i <= numFlowerTypes; i++) {
        scanf("%d", &flowerLimits[i]);
    }

    int dp[numFlowerTypes + 1][totalFlowers + 1];  // 动态规划数组,dp[i][j]表示用前i种花摆j盆花的方案数
    // 初始化边界条件,当没有花时,只有一种摆法(即什么都不摆)
    dp[0][0] = 1;
    for (int j = 1; j <= totalFlowers; j++) {
        dp[0][j] = 0;
    }

    // 动态规划计算过程
    for (int i = 1; i <= numFlowerTypes; i++) {
        for (int j = 0; j <= totalFlowers; j++) {
            // 先初始化为不选第i种花的情况,即用上i - 1种花摆j盆花的方案数
            dp[i][j] = dp[i - 1][j];

            // 再考虑选第i种花的情况,累加不同摆放数量的方案数
            for (int k = 1; k <= flowerLimits[i] && k <= j; k++) {
                dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % MOD;
            }
        }
    }

    // 输出最终结果
    printf("%d\n", dp[numFlowerTypes][totalFlowers]);

    free(flowerLimits);  // 释放动态分配的内存

    return 0;
}

C++ 代码

#include <iostream>
#include <vector>

const int MOD = 1000007;

int main() {
    int numFlowerTypes;  // 花的种类数
    int totalFlowers;  // 总花盆数
    std::cin >> numFlowerTypes >> totalFlowers;

    std::vector<int> flowerLimits(numFlowerTypes + 1);  // 存储每种花的数量限制
    for (int i = 1; i <= numFlowerTypes; i++) {
        std::cin >> flowerLimits[i];
    }

    std::vector<std::vector<int>> dp(numFlowerTypes + 1, std::vector<int>(totalFlowers + 1));  // 动态规划数组
    // 初始化边界条件
    dp[0][0] = 1;
    for (int j = 1; j <= totalFlowers; j++) {
        dp[0][j] = 0;
    }

    // 动态规划计算过程
    for (int i = 1; i <= numFlowerTypes; i++) {
        for (int j = 0; j <= totalFlowers; j++) {
            // 先初始化为不选第i种花的情况
            dp[i][j] = dp[i - 1][j];

            // 再考虑选第i种花的情况,累加不同摆放数量的方案数
            for (int k = 1; k <= flowerLimits[i] && k <= j; k++) {
                dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % MOD;
            }
        }
    }

    // 输出最终结果
    std::cout << dp[numFlowerTypes][totalFlowers] << std::endl;

    return 0;
}

Java代码

import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;

public class FlowerArrangement {
    public static final int MOD = 1000007;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int numFlowerTypes = scanner.nextInt();  // 花的种类数
        int totalFlowers = scanner.nextInt();  // 总花盆数

        List<Integer> flowerLimits = new ArrayList<>();  // 存储每种花的数量限制
        for (int i = 0; i < numFlowerTypes; i++) {
            flowerLimits.add(scanner.nextInt());
        }

        int[][] dp = new int[numFlowerTypes + 1][totalFlowers + 1];  // 动态规划数组
        // 初始化边界条件
        dp[0][0] = 1;
        for (int j = 1; j <= totalFlowers; j++) {
            dp[0][j] = 0;
        }

        // 动态规划计算过程
        for (int i = 1; i <= numFlowerTypes; i++) {
            for (int j = 0; j <= totalFlowers; j++) {
                // 先初始化为不选第i种花的情况
                dp[i][j] = dp[i - 1][j];

                // 再考虑选第i种花的情况,累加不同摆放数量的方案数
                for (int k = 1; k <= flowerLimits.get(i) && k <= j; k++) {
                    dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % MOD;
                }
            }
        }

        // 输出最终结果
        System.out.println(dp[numFlowerTypes][totalFlowers]);

        scanner.close();
    }
}

Python代码

MOD = 1000007

num_flower_types, total_flowers = map(int, input().split())  # 读取花的种类数和总花盆数

flower_limits = [0] + list(map(int, input().split()))  # 存储每种花的数量限制,索引从1开始对应花的种类

dp = [[0] * (total_flowers + 1) for _ in range(num_flower_types + 1)]  # 动态规划二维列表
# 初始化边界条件
dp[0][0] = 1
for j in range(1, total_flowers + 1):
    dp[0][j] = 0

# 动态规划计算过程
for i in range(1, num_flower_types + 1):
    for j in range(0, total_flowers + 1):
        # 先初始化为不选第i种花的情况
        dp[i][j] = dp[i - 1][j]

        # 再考虑选第i种花的情况,累加不同摆放数量的方案数
        for k in range(1, min(flower_limits[i] + 1, j + 1)):
            dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % MOD

# 输出最终结果
print(dp[num_flower_types][total_flowers])

在这里插入图片描述


💐The End💐点点关注,收藏不迷路💐