一开始不知道怎么做,不要紧,我们来列举一下
比如例子:
输入
2 4
3 2
输出
2
有两种花,只能放4盘花,每种花必须按顺序从小到大排序,就是说第二种花是只能放在第一种花后面,第三种花前面。
有以下几种摆法
1、1112
2、1122
两种摆法,然后这两种摆法怎么来的呢,又是从什么状态转移过来的呢
四盘花二种花是从第一种花的三盘花的一种状态加上第一种花的两盘花的状态转移过来的
在限制条件内,第二种花可以摆一盘或者摆两盘,所以dp[2][4]=dp[1][3]+dp[1][2];
而第一种花的状态又是怎么样来的,第一种花只能有一种摆法,一般初始化为1。
根据以上内容,我们就可以得出状态转移方程
每种的限制盘数为ai盘,
for(int j=1;j<=ai;j++){
dp[i][j]+=dp[i-1][j-k];
}
最后输出dp[n][n]即可。
稍微换一个思路,其实这个题也是背包问题,有n个物品,有n种价值,容量有限的情况下,放进去物品的方案数。
注意:
1、要记得取模
2、要记得dp[0][0]=1,什么都没有什么都不放也算一种方案数
3、数很大,记得开long long数组
4、容量从0 开始递增到m,
5、一种种类可以取零盘花,也就是说可以不取一盘花
6、一定要考虑0行的赋值对结果有没有影响,这道题来说是没有影响就没有赋值
(对于初学者来说,想进步知道怎么解,多看多练即可)
废话不多说,上代码:
#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e6 + 7;
int main() {
ios::sync_with_stdio, cin.tie(0), cout.tie(0);
//关闭输入输出流
long long n, m, arr[110], dp[110][110], k;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> arr[i];
}
dp[0][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= m; j++) {
//注意容量从0开始算
for (k = 0; k <= arr[i] && k <= j; k++) {
dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % mod;
}
}
}
cout << dp[n][m];
return 0;
}
这里是红糖,记录我的小白成长史。
如果觉得对你有帮助的话可以点个赞,点个关注,创作不易,请多多支持。
我们下篇文章见!!