动态规划算法

0-1背包问题(动态规划)

主宰稳场 提交于 2019-11-27 00:56:18
问题描述 n个物品和1个背包。对物品i,其价值为vi,重量为 wi,其价值为vi,背包容量为W。如何选取物品装入背包,使背包中所装入的物品的总价值最大? 数据结构的选择 数组w[n]来存放n个物品的重量; 数组v[n]来存放n个 物品的价值; 背包重量为W, 数组m[n+1][W+1]存放每次迭代执行结果; 数组x[n]用来存放所装入背包的物品状态 算法实现与测试 代码实现 package backpack ; import java . util . Scanner ; public class Backpack { /** * 动态规划算法实现 * @param v 存放n个 物品的价值数组 * @param w 存放n个物品的重量数组 * @param W 背包容量 * @param m 存放每次迭代执行结果 */ public static void knapsack ( int [ ] v , int [ ] w , int W , int [ ] [ ] m ) { int n = v . length ; //装入为0,初始化 for ( int i = 0 ; i < n + 1 ; i ++ ) m [ i ] [ 0 ] = 0 ; //背包内没有物品时初始化 for ( int j = 0 ; j < W + 1 ; j ++ ) m [ 0 ] [ j ]

【算法】简单动态规划——三逆数的O(N^2)解法!

泄露秘密 提交于 2019-11-26 20:28:20
问题描述: 三逆数定义:给一个数的序列A[0,1,....N-1]),当i<j<k且A[i]>A[j]>A[k]时,称作ai,aj,ak为一个三逆数。 现在给定一个长度为N的数组,求此数组序列中存在三逆数的总个数。 本人暂时只想到O(N^2)时间复杂度的解法。不知道还没有没更好更快的解法。(谁有更好的解法,欢迎分享~) O(N^3)解法: 这个最直观了,直接三层循环进行统计,即可求和三逆数总和。代码太简单了,就略过了~ O(N^2)解法: 1.进行预处理,先用R[1..N]数组记录,R[i]表示在第i个元素后面比第i个元素小的个数之和,此步为基本的动态规划,时间复杂度为O(N^2)。 for ( int i = 0 ; i< N; ++i) R[i] = 0 ; for ( int i = N- 2 ; i>= 0 ; i-- ) {    for ( int j = i+ 1 ; j <N; ++ j)   {      if (A[i] > A[j]) { R[i] = max(R[i], R[j]+ 1 ); }    } } 2.二层循环枚举每两个元素,并进行累加求总和。 1 for ( int i = 0 ; i< N; ++ i) 2 { 3 for ( int j = i+ 1 ; j< N; ++j ) 4 { 5      ans += (A[j] < A[i])

[动态规划] leetcode 650 2Keys Keyboard

五迷三道 提交于 2019-11-26 14:06:31
problem: https://leetcode.com/problems/2-keys-keyboard/ 重做此题,发现依然只能写出N2的算法,水平并没有提升TAT class Solution { public: int minSteps(int n) { vector<vector<int>> dp(n + 1, vector<int>(n + 1, 10000)); if(n == 1) return 0; dp[1][1] = 1; for(int i = 2;i <= n;i++) { int minnum = INT_MAX; for(int j = 1; j < i; j++) // do parse { dp[i][j] = min(dp[i][j], dp[i - j][j] + 1); minnum = min(dp[i][j], minnum); } dp[i][i] = minnum + 1; // do copy } return *min_element(dp[n].begin(), dp[n].end()); } }; 从评论区拿到的advance版本。这道题的标准解法是分解质因数。最优解的证明已经涉及到一些数学上的问题了。 class Solution { public: int minSteps(int n) { vector<int> dp

【学习笔记】动态规划—各种 DP 优化

雨燕双飞 提交于 2019-11-26 09:20:18
【学习笔记】动态规划—各种 DP 优化 【大前言】 个人认为贪心, \(dp\) 是最难的,每次遇到题完全不知道该怎么办,看了题解后又瞬间恍然大悟(TAT)。这篇文章也是花了我差不多一个月时间才全部完成。 【进入正题】 用动态规划解决问题具有 空间耗费大 、 时间效率高 的特点,但也会有时间效率不能满足要求的时候,如果算法有可以优化的余地,就可以考虑时间效率的优化。 【DP 时间复杂度的分析】 \(DP\) 高时间效率的关键在于它减少了“ 冗余 ”,即不必要的计算或重复计算部分,算法的冗余程度是决定算法效率的关键。而动态规划就是在将问题规模不断缩小的同时,记录已经求解过的子问题的解,充分利用求解结果,避免了反复求解同一子问题的现象,从而减少“ 冗余 ”。 但是,一个动态规划问题很难做到完全消除“ 冗余 ”。 下面给出动态规划时间复杂度的决定因素: 时间复杂度 \(=\) 状态总数 \(×\) 每个状态转移的状态数 \(×\) 每次状态转移的时间 【DP 优化思路】 一:减少状态总数 \((1).\) 改进状态表示 \((2).\) 选择适当的规划方向 二:减少每个状态转移的状态数 \((1).\) 四边形不等式和决策的单调性 \((2).\) 决策量的优化 \((3).\) 合理组织状态 \((4).\) 细化状态转移 三:减少状态转移的时间 \((1).\) 减少决策时间 \(