动态规划算法自学

递推:此时的最优必然是此前所推最优与此时可选方案的比较

1.必然有比较,即有多种方式达到目标。

2.必然与此前最优解有关。

3.必然从0到n,先看小最优再看要求最优。

1.确认dp数组与下标

int dp[i];

int dp[i][j];

明确dp与下标的含义,与关系。

2.递推公式

找最优;

dp[i] = min(dp[i-1],dp[i-2]);

遍历所有路径;

dp[i][j] = dp[i-1][j] + dp[i][j-1];

得到dp数组的途径,一般为两种。选择题目要求最优解(类比贪心局部最优推全局最优)。

3.dp数组如何初始化。

dp[0] = 0;dp[1] = 0;

for(int i=0; i<n; i++)

{

dp[0][i] = 0;

}

一般初始化dp[0]与dp[1],其值可能为0,1.

4.遍历顺序

for(i=0; ;){

        for(j=0; ;)
}

5.举例推导dp函数。

遇到的难题:力扣:96-不同的二叉搜索树。

需要熟悉二叉搜索树和动态规划的概念。

 1.必然从0到n,想求dp[n],先去dp[0]......。

2.dp与下标关系:下标为组成结点,dp为有多少种组成方式。

这题不同之点在于一棵树有两个子树。及需要排列出左右子树的各种组成结点数再相加。

左子树的情况   *  右子树的情况为这一种情况的 种类。

for(int i=1; i<=n; i++)

    {

        for(int j=1; j<=i; j++)

        {

            dp[i] = dp[i] + dp[j-1]*dp[i-j];

        }

    }

 至于二叉搜索中的搜索不用我们担心,我们只知道结点数,其值将由系统自动分配。

动规:01背包问题

力扣416:分割等和子集问题

    确认dp数组以及下标含义(套入01背包),三个要素,容量,重量,条件(是刚好装满,还是价值最高):

二维01背包:dp[i][j];

i:存入的第几个数,j:背包的容量。条件:刚好装满(即最大重量 ==最大容量 )。

dp数组的初始化:

分别判断i=0,与j=0的情况,考虑初始化。

当j=0时,重量为0,当i = 0时,不装都为0,能装都为nums[i]

则全初始化为0;

状态方程:

经典01背包状态方程:

dp[i][j] = max(dp[i-1][j], dp[i-1][j-nums[i]]);

遍历顺序:

for(i=1; i<numsSize; i++)//先遍历物品,每个物品只被使用一次。

    {

        for(j=0; j<=sum/2; j++)//再遍历容量。

        {

            if(j>=nums[i])

            {

                dp[i][j] = max(dp[i-1][j],dp[i-1][j-nums[i]]+nums[i]);

            }

            else

            {

                dp[i][j] = dp[i-1][j];

            }

        }

    }

二维与一维需要注意:

遍历顺序的不同:一维只能先遍历物品再遍历容量。且容量由大到小遍历,避免装入重复元素。

 又一种01背包类型题,从找背包容量到状态方程都有很大不同

 定义dp数组

明确dp数组及其下标含义

dp【】表示有多少种方法,下标标识背包容量为多少时有多少种方法,i表示处理第i个物品时不同背包容量会得到的总次数。

背包容量为x-(sum-x) =  target  -》 x = (sum+taget)/2;

所求的即是当 j = x 时,且遍历完 i 后,得到的次数。

比较奇特的状态方程

for(i=0; i<numsSize; i++)

    {

        for(j=(target+sum)/2; j>=nums[i]; j--)

        {

            dp[j] += (dp[j-nums[i]]);

        }

    }

    return dp[(target+sum)/2];

dp【j】 = 上一个物品在不考虑当前物品本身容量情况下的最多次数+上一个物品在最大容量时的最多次数。

又思考了一天后,明白这个状态方程。

dp[j](当出现新的物品时,将这个物品放或不放进去)

= dp[j](不放,即没有变化,上一个物品已经可以组成的可能性和次数)

+ dp[j-nums[i]](放入,即产生了新的变化,减去了新物品的重量后,还可以有多少种可能,因为加入了新元素,则都是新的装满背包的可能性)。

完全背包:

1)求组合数是外层循环物品,内层遍历容量

2)求排列数(不同顺序也可),先遍历外层容量,再遍历内层物品。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然!下面是一个简单的自学人工智能的路线图供您参考: 1. 数学基础:学习线性代数、概率论和统计学。这些是人工智能的基础,对于理解算法和模型非常重要。 2. 编程基础:学习一种或多种编程语言,如Python或Java。熟悉基本的编程概念和数据结构。 3. 机器学习:了解机器学习的基本概念和算法,如回归、分类、聚类等。掌握常见的机器学习库,如scikit-learn。 4. 深度学习:学习神经网络和深度学习的原理。了解常见的深度学习框架,如TensorFlow和PyTorch。 5. 自然语言处理:了解自然语言处理的基本技术,如文本分类、命名实体识别等。掌握常见的自然语言处理库,如NLTK和spaCy。 6. 计算机视觉:学习计算机视觉的基本概念和技术,如图像分类、目标检测等。熟悉常见的计算机视觉库,如OpenCV。 7. 强化学习:了解强化学习的原理和算法,如Q-learning、深度强化学习等。掌握常见的强化学习库,如OpenAI Gym。 8. 部署和优化:学习如何将模型部署到生产环境,并进行性能优化和调试。 9. 实践项目:完成一些实际的人工智能项目,如图像分类、情感分析等。这将帮助您巩固所学知识,并提升实践能力。 请注意,这只是一个简单的路线图,您可以根据自己的兴趣和需求进行调整。此外,不断阅读相关文献、参加在线课程和加入社区讨论也是自学人工智能的有效方式。祝您在自学人工智能的过程中取得成功!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值