动规入门题目题解-蓝桥oj389摆花(初学者必看)

题目链接

一开始不知道怎么做,不要紧,我们来列举一下

比如例子:

输入

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;
}

这里是红糖,记录我的小白成长史。

如果觉得对你有帮助的话可以点个赞,点个关注,创作不易,请多多支持。

我们下篇文章见!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值