第三讲 简单数论和动态规划

典型01动态规划例题讲解:非常详细

地址:典型01动态规划例题视频讲解
整体模板:

for(int i = 1; i <= n ; i ++)
	for(int j = 1; j <= m; j ++)
	{
		if(j < w[i])//如果当前的物品重量大于所能容纳重量,不选
			f[i][j] = f[i-1][j];
		else // 如果当前包包可以装得下,就取选和不选的最大值
		{
			f[i][j] = max(f[i-1][j], f[i-1][j - w[i]] + v[i]);
		}
	}

题目:01背包问题

题解:

#include
#include
#include
#include

using namespace std;

const int N = 1010;

int f[N][N];
int v[N], w[N];
int n, m;


int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) cin >> v[i] >> w[i];
    
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= m; j ++)
        {
            if (j < v[i])//不能装下
                f[i][j] = f[i-1][j];
            else
                f[i][j] = max(f[i-1][j], f[i-1][j-v[i]] + w[i]);
        }
    
    cout << f[n][m] << endl;
    return 0;
}

闫氏DP分析法:
主要思想:
第三讲 简单数论和动态规划_第1张图片
思考:从状态计算开始思考,下一个状态是前面几个状态的最大值,然后前面一个状态又可以由之前的状态来表示,这就把问题的方案转化为子问题的方案来解决。那一个最典型的例子来举例:
地址: 数字三角

1.1 首先是状态计算:以第二层为例子,他当前所能表示的最大值为: 取上一层左右两边节点的最大值+ 他自己的值。
公式: f[i][j] = max(f[i-1][j-1],f[i-1][j]) + w[i][j];

1.2 这个地方的状态表示中的属性为:Max
1.3 集合:从第一层走到底层的所有路径节点之和。取一个最大值

1.4 需要注意的小细节:如果节点可以取负数,并且DP属性 是Max,这个时候需要把状态数组f[i][j]全都设置为最小值,因为0会比负数大,就不会取到负数了。最小的负数:-INF = -0x3f3f3f;

你可能感兴趣的:(算法,动态规划,算法)