动态规划

动态规划案例――最长公共子序列LCS

匿名 (未验证) 提交于 2019-12-02 23:05:13
以上为LCS的一个最优子结构定理,据此可以得到递归公式如下(c[i][j]表示当前匹配到的LCS的长度) 根据如下矩阵计算LCS 以下为java实现: package bluebrige; import java.util.Scanner; public class Lcs { static int [][]c=new int[8][7]; static int [][]b=new int[8][7];//保存路径,对于不同情况分别取-1,-2,-3三个状态值,以找到一个LCS public static void lcsLength(char x[],char y[]) { } public static void printLcs(char x[],int i,int j) { } } 文章来源: https://blog.csdn.net/Aaron_1997/article/details/87249406

SDNUOJ 1292 动态规划之LDS(最长下降子序列)

匿名 (未验证) 提交于 2019-12-02 23:03:14
Description 昨天是平安夜,圣诞老人从房顶上的烟囱里爬到小朋友床边把礼物送给梦乡中的小朋友,但是今年的圣诞老人是处女座的,他有很严重的强迫症,他从一条街的一端开始,每次送礼物进的烟囱都不能比之前进的烟囱高,而且他还想要送出最多的礼物。 Input 输入数据只有一行,该行包含若干个数据,表示一条街上的烟囱高度(烟囱最多有 20 枚,高度h≤1000000)。 Output 圣诞老人最多送出多少礼物。 Sample Input 315 199 155 301 215 170 150 25 Sample Output 6 #include<bits/stdc++.h> using namespace std; int cmp(int a, int b) { return a > b; } int main() { int s[25];///存:序列各元素 int dp[25];///存:到第i个元素为止最长单调子序列的长度(i从0开始) memset(s, 0, sizeof(s)); memset(dp, 0, sizeof(dp)); int k = 0; int a; while(cin >> a) { s[k] = a; k++; } int ans = 0; for(int i = 0; i < k; i++)///从头开始 { dp[i] = 1;///先初始化为1

【动态规划】机器分配

匿名 (未验证) 提交于 2019-12-02 23:03:14
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ssllyf/article/details/84886339 机 器 分 配 机器分配 机 器 分 配 Description 总公司拥有高效生产设备M台,准备分给下属的N个公司。各分公司若获得这些设备,可以为国家提供一定的盈利。问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值。其中M《=15,N〈=10。分配原则:每个公司有权获得任意数目的设备,但总台数不得超过总设备数M。 Input 第一行保存两个数,第一个数是设备台数M,第二个数是分公司数N。接下来是一个M*N的矩阵,表明了第I个公司分配J台机器的盈利。 Output 最大盈利 Sample Input 15 10 36 67 86 8 82 88 1 96 75 82 107 68 136 105 99 104 61 176 127 133 184 120 223 179 198 134 113 247 225 205 283 136 273 217 249 140 117 312 296 205 286 207 315 306 291 224 209 346 370 272 292 279 317 332 372 227 223 375 370 295 361 327 363 373 453 277 286

最优二叉查找树_动态规划

匿名 (未验证) 提交于 2019-12-02 23:03:14
原问题是给出各个节点和各个节点的被查找概率,然后构造一棵各个节点平均被查找比较次数最小的树,则该问题可以用动态规划来解决 示例如下 推广到一般的情况,并设T(i, j)是由记录{ri, …, rj}(1≤i≤j≤n)构成的二叉查找树,C(i, j)是这棵二叉查找树的平均比较次数,有下列分析 观察这个表,可知可知左边的表的第一行的第四列就是我们要求的最优平均比较次数,而右边的表我们可以知道在c(i ,j)得到最优解,即平均查找次数最小的根节点,比如一共四个节点,则我们从右边的R(1,4)的值即3是这四个节点构成的树的根节点。则树的左子树变为c(1,2),他的根节点是r(1,2)=2,然后2又有左节点1,而4则是3的根节点。则树的样子便出来了。 代码如下 1 #include<bits/stdc++.h> 2 using namespace std; 3 double BST(int n,double p[],double c[][100],int r[][100]) 4 { 5 for(int i=1;i<=n;i++){//按式1和式2初始化 6 c[i][i-1]=0; 7 c[i][i]=p[i]; 8 r[i][i]=i; 9 } 10 c[n+1][n]=0; 11 for(int d=1;d<n;d++){//安对角线计算,此时是n-1个对角线 12 for(int i

用Python解决TSP问题(2)――贪心算法

匿名 (未验证) 提交于 2019-12-02 22:54:36
文章源码在Github: https://github.com/jinchenghao/TSP 本介绍用python解决TSP问题的第二个方法――动态规划法 算法介绍 动态规划算法根据的原理是,可以将原问题细分为规模更小的子问题,并且原问题的最优解中包含了子问题的最优解。也就是说,动态规划是一种将问题实例分解为更小的、相似的子问题,并存储子问题的解而避免计算重复的子问题,以解决最优化问题的算法策略。 我使用DP求解TSP问题的主要分为三个主要部分: T(s,init)代表的意思是从init点出发经过s中全部的点回到init的距离。 程序 输入: 1 2066 2333 2 935 1304 3 1270 200 4 1389 700 5 984 2810 6 2253 478 7 949 3025 8 87 2483 9 3094 1883 10 2706 3130 代码: """ 动态规划法 name:xxx date:6.8 """ import pandas as pd import numpy as np import math import time dataframe = pd.read_csv("./data/TSP10cities.tsp",sep=" ",header=None) v = dataframe.iloc[:,1:3] train_v= np

动态规划 矩阵连乘问题 python

匿名 (未验证) 提交于 2019-12-02 22:54:36
习要学的,博客是要写的,怪兽是要慢慢打的。 m=[[0,0,0,0,0],#储存计算最优值 [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0] ] s=[[0,0,0,0,0],#储存最佳分开位置 [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0] ] p=[2,3,4,5,6] r=2 n=4 while(r<=n):#按列循环 i=1 while(i<=(n-r+1)):#按行循环 j=i+(r-1) m[i][j]=m[i][i]+m[i+1][j]+p[i-1]*p[i]*p[j] s[i][j]=i k=i+1 while(k<j):#行内找出最优解,并存入mzho t= m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j] if t<m[i][j] : m[i][j]=t s[i][j]=k k+=1 i+=1 r+=1 row=0 while (row<=4): print(s[row]) row+=1 row=0 while (row<=4): print(m[row]) row+=1 def traceback(i,j): if i==j: return traceback(i,s[i][j]) traceback(s[i][j]+1,j)

字符串的编辑距离-动态规划-Python

匿名 (未验证) 提交于 2019-12-02 22:54:36
问题描述: 给定两个字符串A和B,要用最少的操作将字符串A转换成字符串B。其中字符串操作包括: (1)删除一个字符(Insert a character) (2)插入一个字符(Delete a character) (3)修改一个字符(Replace a character) 将字符串A转换成B串所用的 最少 字符 操作数 称为字符串A到 B的编辑距离, 又称为L evenshtein距离,是在1965年, 俄罗斯数学家Vladimir Levenshtein提出的。 问题分析: 动态规划思想 (1)、dp[i][j]表示将字符串 转变为 的最小步骤数。 (2)、边界情况: 不断添加字符 ,dp[0][j] = j。 不断删除字符 ,dp[i][0] = i。 (3)、对应三种字符操作方式: 插入操作 :dp[i][j - 1] + 1 相当于为 B 串的最后插入了 A 串的最后一个字符 ; 删除操作 ; 替换操作 :dp[i - 1][j - 1] +(A[i - 1] != B[j - 1])相当于通过将 B 串的最后一个字符替换为 A 串的最后一个字符。 (4)所以 dp方程式 为: Python实现(时间复杂度:O(mn),空间复杂度:O(mn)): class Solution: def minDistance(self, word1, word2): """ :type

动态规划:leetcode 32 最长有效括号

你离开我真会死。 提交于 2019-12-02 21:30:56
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。 案例: 输入: ")()())" 输出:4 输入: "()(())" 输出:6 public int longestValidParentheses(String s) { //储存最大长度,返回 int max = 0; //状态数组,数组元素存储当前往前的括号有效的长度 int[] dp = new int[s.length()]; //循环,从第二个元素开始往前搜索解答,把结果储存在状态矩阵中 for (int i = 1; i < s.length(); i++) { //当当前的符号是 ')' ,这时候的括号往前是有效的,如果是'(',那么这时对应状态数组中存储为0,为无效括号 if (s.charAt(i) == ')') { //如果前一个符号为'(',那么当前的括号是有效的,最长有效括号长度为其前一个加2 if (s.charAt(i - 1) == '(') { dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;// 如果i>=2 那这时的dp应该为: dp[i] = dp[i-2] + 2 //如果前一个为')',则需要分情况, } else if (i - dp[i - 1] - 1 >= 0 && s.charAt(i - dp[i - 1] - 1)

石头合并---动态规划详解

£可爱£侵袭症+ 提交于 2019-12-02 20:52:54
思想来源: 1 : floyd 2 :隔板法 3 :动态规划 问题分析: 1 :只能是相邻两个石头才能合并 2 :操场是圆形的 3 :合并后的石头组成一个新的石堆 4 :要求求解最优的合并方式使得得分最大 根据题意 什么才叫得分? 得分是合并的石头形成新的石堆的石头的数目,合并一个对应的得分就加上新合并的石堆石头的数目, 最后求解的分的总和 算法选择 • 蛮力法 时间复杂度大效率低下 • 贪心法 石头的堆数目相近的比较多时处理复杂 并且难以的到最优解 • 动态规划 下面将介绍 数据模拟 • 加入有石堆 石子 数目一次是 1 2 3 则选择方式有 1): 1 ->2->3; 3+6 = 9 2)2->1->3 ; 3+6 = 9 3)2->3->1 ; 5+6 = 11 4)1->3->2 ; 4+6 = 10 5)3->1->2 ; 4+6 = 10 6)3->2->1 ; 5+6 = 11 故最优解为 11 动态方程 约束条件 : 1=k<=j-1; 方程: F(I,j) = max{f(I,k)+f(i+k,j-k)}+sum[i][j]; 源码 #include <iostream> using namespace std; const int NUM = 100; int a[NUM]; int c[NUM][NUM]; int n; int value(int i,int

动态规划 石子合并

我只是一个虾纸丫 提交于 2019-12-02 20:41:49
http://lx.lanqiao.cn/problem.page?gpid=T414 问题描述   在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数。求把所有石子合并成一堆的最小花费。 输入格式   输入第一行包含一个整数n,表示石子的堆数。   接下来一行,包含n个整数,按顺序给出每堆石子的大小 。 输出格式   输出一个整数,表示合并的最小花费。 样例输入 5 1 2 3 4 5 样例输出 33 数据规模和约定   1<=n<=1000, 每堆石子至少1颗,最多10000颗。 动态规划方程: 1 . i==j dp[i][j] = 0 2. i!= j dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[i][j]) 解题思路: 合并石子的过程中 ,每一次都是将两堆石子合并成一堆,动态规划的思想就是根据要合并的这两堆已经是最优解,求出两个的和为最优 dp[i][j]的含义: 从第i个石子到第j个石子进行合并的最优解 ; sum[i][j]的含义:从第i个石子到第j个石子的总重量; #include <cstdio> #include <cstdlib> #include <iostream> using namespace std; const int