动态规划

旅行商问题的动态规划解法

二次信任 提交于 2019-12-01 18:25:38
一个售货员必须访问n个城市,这n个城市是一个完全图,售货员需要恰好访问所有城市的一次,并且回到最终的城市。 城市与城市之间有一个旅行费用,售货员希望旅行费用之和最少。 旅行商问题是np问题,一般可以使用回溯法或者动态规划解决。 class Solution: def __init__(self, X, start_node): self.X = X self.start_node = start_node self.array = [[0] * (2 ** (len(self.X) - 1)) for i in range(len(self.X))] def transfer(self, sets): su = 0 for s in sets: su = su + 2 ** (s - 1) return su def tsp(self): s = self.start_node num = len(self.X) cities = list(range(num)) cities.pop(cities.index(s)) node = s return self.solve(node, cities) def solve(self, node, future_sets): if len(future_sets) == 0: return self.X[node][self.start

动态规划

我与影子孤独终老i 提交于 2019-12-01 17:31:38
1)给定一个矩阵,矩阵每个位置都有对应的数值。从矩阵左上角到右下角,找出最小和    //只能向右或者向下dp[i][j] = max( dp[i-1][j] , dp[i][j-1] ) + a[i][j] ; 来源: https://www.cnblogs.com/Shallow-dream/p/11695908.html

后台开发面经1

白昼怎懂夜的黑 提交于 2019-12-01 15:42:13
1、八大数据结构及分类 1、数组 频繁查询,对存储空间要求不大,很少增加和删除的情况 2、栈 栈常应用于实现递归功能方面的场景,例如斐波那契数列 3、队列 因为队列先进先出的特点,在多线程阻塞队列管理中非常适用 4、链表 数据量较小,需要频繁增加,删除操作的场景 5、树 二叉树既有链表的好处,也有数组的好处,是两者的优化方案,在处理大批量的动态数据方面非常有用。 6、散列表 哈希冲突的问题,如果处理的不好会浪费大量的时间,导致应用崩溃 7、堆 因为堆有序的特点,一般用来做数组中的排序,称为堆排序 8、图 https://blog.csdn.net/yeyazhishang/article/details/82353846 因为哈希表是基于数组衍生的数据结构,在添加删除元素方面是比较慢的,所以很多时候需要用到一种数组链表来做,也就是拉链法。拉链法是数组结合链表的一种结构,较早前的hashMap底层的存储就是采用这种结构,直到jdk1.8之后才换成了数组加红黑树的结构。 图是一种比较复杂的数据结构,在存储数据上有着比较 复杂和高效 的算法,分别有 邻接矩阵 、邻接表、十字链表、邻接多重表、边集数组等存储结构 2、堆栈特点及应用 栈:特点就是一个先进后出的结构。 队列:特点就是一个先进先出的结构。 栈的应用 :非常广泛,在CPU内部就有提供栈这个机制。主要用途: 函数调用和返回

10.16 动态规划(一)

好久不见. 提交于 2019-12-01 12:11:50
区间DP P1220 关路灯 代码: ```cpp #include <cstdio> #include <cstring> #define min(a,b) ((a)<(b)?(a):(b)) typedef long long ll; const int N = 55; const ll INF = 0x3f3f3f3f3f3f3f3fll; ll f[N][N][2]; int P[N], L[N], n, c, pre[N]; int main(){ scanf("%d%d", &n, &c); for(int i = 1; i <= n; ++i){ scanf("%d%d", L+i, P+i); pre[i] = pre[i-1] + P[i]; } for(int l = 1; l <= n; ++l){ for(int i = 1, j; (j = i + l - 1) <= n; ++i){ if(i <= c && c <= j){ f[i][j][0] = min( f[i+1][j][0] + (L[i+1] - L[i]) * (pre[n] - pre[j] + pre[i]), f[i+1][j][1] + (L[j] - L[i]) * (pre[n] - pre[j] + pre[i]) ); f[i][j][1] = min( f[i][j-1

[POI2013]BAJ-ytecomputer [动态规划]

人盡茶涼 提交于 2019-12-01 11:59:00
[POI2013]BAJ-ytecomputer P3558 [POI2013]BAJ-Bytecomputer 给一个只包含-1,0,1的数列,每次操作可以让a[i]+=a[i-1],求最少操作次数使得序列单调不降 还是很好想的 这样操作下来最后序列里的数也肯定都为-1,0,1 用 \(f[i][0/1/2]\) 表示数组前 \(i\) 个数单调不下降时第 \(i\) 个数为 \(-1/0/1\) 然后就分情况转移就是了== (感觉很简单 它失去了它作为紫题的尊严) int main(){ #ifndef ONLINE_JUDGE freopen("T3.txt","r",stdin); #endif rd(n); for(int i=1;i<=n;++i) rd(a[i]); memset(f,inf,sizeof(f)); f[1][a[1]+1]=0; for(int i=2;i<=n;++i){ if(a[i]==-1) f[i][0]=f[i-1][0],f[i][2]=f[i-1][2]+2; else if(!a[i]) f[i][0]=f[i-1][0]+1,f[i][1]=Min(f[i-1][0],f[i-1][1]),f[i][2]=f[i-1][2]+1; else f[i][0]=f[i-1][0]+2,f[i][1]=f[i-1][0]+1,f[i]

算法第二章作业

[亡魂溺海] 提交于 2019-12-01 10:23:47
1. 对于分治法思想的体会 分治法的思想是将一个大的问题,拆分成多个规模较小的问题,最后再将各个小规模的问题合并,最终解决原问题的方法。 个人感觉,分治法是一种从大到小的方法,而动态规划则是在分治法的基础上,再从下到上的方法。将大的问题拆分成一个个小的部分,但在真正实现时,是从每一个小的问题向上走的。 分治法是将大问题都分割成许多个规模一样的小问题,各个问题之间往往是互相独立的,但动态规划则适用于各个问题之间是有关联的,在这种情况下,如果仍然使用分治法,则会对同一个问题进行多次重复计算,耗费了资源。 因此有些时候要先分析问题,在分割之后,各个问题之间是否有关联,如果有关联则要使用动态规划,否则才能使用分治法。 2. 结对编程情况汇报 在结对编程中,因为搭档珞洋很强,所以基本上是他带我,有问题也是找他询问,他总能很及时很详细地解答我的问题。在此感谢感谢! 来源: https://www.cnblogs.com/smallsprings/p/11681445.html

[SOJ407] 球【动态规划】【组合数学】

孤者浪人 提交于 2019-12-01 10:18:35
题意简述:有 \(n\) 个桶和 \(2n-1\) 个球,每个桶最多能装一个球,且第 \(i\) 个桶可以装前 \(2i-1\) 个球。问取 \(m\) 个桶和 \(m\) 个球,并将每个球放进一个桶里的方案数, \(q\) 组询问。 \(1\leq q\leq 10^5, 1\leq m\leq n\leq 10^7\) 。 有一个显然的 \(O(nm)\) dp:设 \(f_{i, j}\) 为前 \(i\) 个桶选了 \(j\) 个桶的方案数,考虑转移: 若第 \(i\) 个桶不选,则 \(f_{i-1, j}\Rightarrow f_{i, j}\) 。 若第 \(i\) 个桶选,则前 \(2i-1\) 个球中有 \(j-1\) 个已经被选,剩余的可以自由选择,即 \(f_{i-1, j-1}\cdot (2i-j)\Rightarrow f_{i, j}\) 。 然后我们就可以打表啦! 观察发现 \(f_{n, m}=\binom{n}{m}^2\cdot m!\) ,但是这个结论需要证明。 由这个式子 不难 想到, \(n\times n\) 的棋盘中放 \(m\) 个无标号的互不攻击的车也是这个方案数,证明可以设 \(g_{i, j}\) 为 \(i\times i\) 的棋盘放 \(j\) 个车的方案数,考虑棋盘第 \(n\) 行、列(记为 \(S\) )的情况:

动态规划 初级背包问题。。

流过昼夜 提交于 2019-12-01 09:00:56
状态转移方程 B[n][w]=B[n-1][w-W[i]]+V[i] 表示取走第n个物品,重量为W时的价值量。 W V分别存放重量和价值的数组。#include<iostream> #include<vector> #include<math.h> // 背包问题 using namespace std; int value[]={3,4,5,8,10}; int weight[]={2,3,4,5,9}; const int N=5; const int W=20; int B[N+1][W+1]; int main() { for(int i=1;i<=N;++i) { for(int k=1;k<=W;++k) { if(weight[i-1]>k) { B[i][k]=B[i-1][k]; } else { B[i][k]=max(B[i-1][k],B[i-1][k-weight[i-1]]+value[i-1]); } } } cout<<B[N][W]; return 0; } 来源: https://www.cnblogs.com/yangshengjing/p/11674756.html

动态规划-编辑距离

◇◆丶佛笑我妖孽 提交于 2019-12-01 08:59:19
LeetCode72题: 1. 根据str1和str2的长度构建空矩阵 2. 将矩阵第一行和第二行赋上步数,如下,从左往右看,数字代表由最左边空字符''变为'j','ja',......,'jarrry'等的操作总步数 3. 从矩阵第二行开始遍历(即range(1,len(str1)+1)),str1的每个字符与str2中的'j','ja',......,'jarrry'比较 如果相等,则步数d为0 如果不等,步数d为1 此位置的总步数为matrix[i][j-1]+1, matrix[i-1][j], matrix[i-1][j-1]+d的最小值 4. 最终的总步数为matrix[len(str1)][len(str2)],即矩阵右下角的数字 下图是动态规划路径: python代码: def edit_distance(str1, str2): len1, len2 = len(str1), len(str2) matrix = [[0 for _ in range(len2+1)] for _ in range(len1+1)] for i in range(len1+1): matrix[i][0] = i for j in range(len2+1): matrix[0][j] = j for i in range(1, len1+1): # 注意从1开始 for j in

动态规划-划分数组的最大和 Split Array Largest Sum

早过忘川 提交于 2019-12-01 08:58:32
2019-10-14 22:13:18 问题描述 : 问题求解 : 经典的动态规划问题。 public int splitArray(int[] nums, int m) { int n = nums.length; long[][] dp = new long[m + 1][n]; long[] presum = new long[n]; long curSum = 0; for (int i = 0; i < n; i++) { curSum += nums[i]; presum[i] = curSum; dp[1][i] = curSum; } for (int i = 2; i <= m; i++) { for (int j = 0; j < n; j++) { dp[i][j] = curSum; for (int k = 0; k < j; k++) { dp[i][j] = Math.min(dp[i][j], Math.max(dp[i - 1][k], presum[j] - presum[k])); } } } return (int)dp[m][n - 1]; }    来源: https://www.cnblogs.com/hyserendipity/p/11674576.html