动态规划

很伤心写的时候 恰好这个时候 老师问我什么是动态规划 要我说我吱吱呜呜的说了 ”一句保存前面的数组,由局部计算。。“ 本来想补充 再计算的时候很方便可以直接在 o1的时间找到  这个我都没有说脸很红 低下头 

回来我想了一会大概意思就是这样我也找了一下其他大神如何留言 其实也就是 要找到状态方程式什么的 我知道 我研究很多天我一直搞不明白什么是状态方程式 也不喜欢说这么复杂 虽然现在明白了 但是想必很多小白应该也不喜欢 也搞不懂 那么今天我就说一道题目  全面剖析




这个是题目 例子也有

首先 输入2个数表示 第一个一共多少数  第二个是和 

5 和15 

接下来就是求和需要的数 

理解题目意思那么就开始了

如果我们 只有一个数 5 我们要求和 15 可能吗 毫无疑问当然不可以 那么1 可以吗 2可以吗 好像都不行 那么我们就可以建立一张表 列出1 ,2 ,3,4,5,6.。。。15

这个是第一行的数据 0位置我没有放任何东西 一会编程需要

那么我们有2个数了 再添加一个 5 我们重新建立一个表

 

可以想象 第一个5 是一种情况 第二个5也是1种情况 10也有一种情况 就是5+5 

那么我再举个例子 就可以开始说这个规律了

再来一个数10


我们开始思考上文有什么规律

首先是第一个5  定义为1

接下来就是第二个5 我们可以想一下 第2个5 是不应该是第一个5和第2个5 这是两种情况所以是2种情况 (这个相当于废话)

那么考虑上一个5的情况是不是 第一排的(5,5)号坐标下面有个数1  那么是否可以认为 这个一加一个1就是2了 还有一个1 哪里来 这个时候0号就可以派上用途了 


看这个是不是填充了0的位置都是1 那么这个1就可以这样来了 0号位置一堆 所以说不难想象 只能在第一排的0号位置或者第2排的0号位置获得

所以我们得考虑是在哪个位置  那么我们可以看第3行10    如果有20这个数 是不是应该是上一个 0+1 刚刚满足 这个10 是第2排的(5,10) 还是第3排的(10,10)呢

毫无疑问是第二排的10 

因此这个表一直下去也就完成了这个题目接下了 尝试自己画就可以解出来了

#include <iostream>
using namespace std;
int main()
{
	int n, m;
	cin >> n;
	cin >> m;
	int* arr = new int[n];
	for (int i = 0; i<n; i++)
	{
		cin >> arr[i];
	}
	long long **brr = new long long*[n + 1];
	for (int i = 0; i<n + 1; i++)
	{
		brr[i] = new long long[m + 1];
		for (int j = 1; j<m + 1; j++)
		{
			brr[i][j] = 0;
			brr[i][0] = 1;
		}
	}
	for (int i = 1; i<n + 1; i++)
	{
		for (int j = 0; j<m + 1; j++)
		{
			if (j<arr[i - 1])
			{
				brr[i][j] = brr[i - 1][j];
			}
			else
				brr[i][j] = brr[i - 1][j] + brr[i - 1][j - arr[i-1]];
		}
	}
	cout << brr[n][m];
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值