【NOIP普及组】摆花
- C语言代码
- C++ 代码
- Java代码
- Python代码
💐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 1000007int 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 = 1000007num_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💐点点关注,收藏不迷路💐 |