题目
P1077 摆花
题目描述
小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆。通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号。为了在门口展出更多种花,规定第i种花不能超过a_i 盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列。
试编程计算,一共有多少种不同的摆花方案。
分析
题目大意是
有n种花,各有a[i]盆,希望摆m长度的花在外面,问有多少种方法。
先摆x盆,摆k长度,这就存在着状态, 所以可以用动态规划来解。
#include<iostream>
using namespace std;
const int maxn = 105, mod = 10000007;
int n, m, a[maxn], f[maxn][maxn];
int main () {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
f[0][0] = 1;
for (int i = 1; i <= n; i++) { //种类
for (int j = 0; j <= m; j++) { //长度
for (int k = 0; k <= min(a[i], m); k++) {
f[i][j] = (f[i][j] + f[i-1][j-k])%mod;
//这里可以简化,因为i只与i-1有关
}
}
}
cout << f[n][m];
return 0;
}
记忆化搜索和上面的想法一样的
#include<iostream>
using namespace std;
const int maxn = 105, mod = 10000007;
int n, m, a[maxn], f[maxn][maxn];
int dfs(int x, int k) {
if (k > m) return 0;
if (k == m) return 1;
if (x == n+1) return 0;
if (f[x][k]) return f[x][k];
int ans = 0;
for (int i = 0; i <= a[x]; i++) ans = (ans+dfs(x+1,k+i))%mod;
f[x][k] = ans;
return ans;
}
int main () {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
cout << dfs(1, 0) << endl;
return 0;
}
firm
n. 商行; 商号; 公司;
adj. 坚固的; 坚硬的; 结实的; 坚定的; 确定的; 坚决的; 牢固的; 稳固的;
adv. 稳固地;