动态规划

动态规划 01背包问题

ぐ巨炮叔叔 提交于 2019-12-03 01:55:21
0-1背包 Description 给定n(n<=100)种物品和一个背包。物品i的重量是wi,价值为vi,背包的容量为C(C<=1000)。问:应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i只有两个选择:装入或不装入。不能将物品i装入多次,也不能只装入部分物品i。 Input 共有n+1行输入: 第一行为n值和c值,表示n件物品和背包容量c; 接下来的n行,每行有两个数据,分别表示第i(1≤i≤n)件物品的重量和价值。 Output 输出装入背包中物品的最大总价值。 Sample Input 1 5 10 2 6 2 3 6 5 5 4 4 6 Sample Output 1 15 分析 :   n为有n个物品,c为背包空间   设dp[i][j]为在前i个物品中选择,背包空间为j时,装入的最大价值,初始化:边界0初始化为0,答案在dp[n][c]   如果当前j装得下 j >= obj_weight ,状态方程:   dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - obj_weight] + obj_price);   如果当前j装不下,状态方程:   dp[i][j] = dp[i - 1][j];   #include <iostream> using namespace std;

最小m子段和(动态规划)

五迷三道 提交于 2019-12-03 01:38:46
问题描述: 给定n个整数组成的序列,现在要求将序列分割为m段,每段子序列中的数在原序列中连续排列。如何分割才能使这m段子序列的和的最大值达到最小? 输入格式: 第一行给出n,m,表示有n个数分成m段,随后一行给出n个数,以空格分隔 输入样例: 9 3 9 8 7 6 5 4 3 2 1 输出样例: 17 解释: 9 8 | 7 6 | 5 4 3 2 1,9个数分成3段所有情况里这种分法的最大子段和(17)最小。 思路: 动态规划的一种模板,包括矩阵连乘,石子归并等问题。先是考虑分的段数,然后考虑起点/终点,最后是每段中分割点的位置。 本题中使用 dp[i][j]表示前i个数分成j段里最小的最大子段和,则dp[i][j]=min{dp[i][1]-dp[k][1],dp[k][j-1] (1<=k<i)}; 代码: #include<bits/stdc++.h> using namespace std; #define N 99 #define inf 0x3f3f3f3f int a[N],dp[N][N];//dp[i][j]表示前i个数分j段所有情况里最大子段和最小的 int main() { int n,m; cin>>n>>m; for(int i=1; i<=n; i++) cin>>a[i]; for(int i=1; i<=n; i++) dp[i][1]=dp[i

BFS,DFS,动态规划的总结

匿名 (未验证) 提交于 2019-12-03 00:43:02
1.DFS Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighbouring. The same letter cell may not be used more than once. For example, Given board = [ ["ABCE"], ["SFCS"], ["ADEE"] ] word = "ABCCED", -> returns true, word = "SEE", -> returns true, word = "ABCB", -> returns false. 链接为: https://leetcode.com/problems/word-search/description/ 典型DFS题,选择board中其中一个字母为首字母,匹配word,匹配成功选择下一个在匹配,否则返回。匹配下一个有四种情况:左右上下,每种情况成功时,再按上述步骤递归处理。需要注意的是,去重问题,就是不要访问以前访问过的点

(第二场)A Run 【动态规划】

匿名 (未验证) 提交于 2019-12-03 00:43:02
链接: https://www.nowcoder.com/acm/contest/140/A 题目描述: White Cloud is exercising in the playground. White Cloud can walk 1 meters or run k meters per second. Since White Cloud is tired,it can‘t run for two or more continuous seconds. White Cloud will move L to R meters. It wants to know how many different ways there are to achieve its goal. Two ways are different if and only if they move different meters or spend different seconds or in one second, one of them walks and the other runs. 输入描述: The first line of input contains 2 integers Q and k.Q is the number of queries.(Q<=100000,2<=k<=100000)

【动态规划】机器分配

匿名 (未验证) 提交于 2019-12-03 00:43:02
问题 J: 【动态规划】机器分配 时间限制: 内存限制: 64 MB 提交: 解决: 4 [ 提交 ] [ ״̬ ] [ 讨论版 ] [命题人: ] 题目描述 魔法学院购进高效生产设备M台以转换魔法石能量,准备分给学院的N个小组。各小组若获得这些设备,可以为学院提供一定的魔法石能量。问:如何分配这M台设备才能使魔法石能量最大?求出最大魔法石能量值。其中M≤15,N≤10。分配原则:每个小组有权获得任意数目的设备,但总台数不得超过总设备数M。 输入 第一行保存两个数,第一个数是设备台数M,第二个数是小组数N。接下来是一个M×N的矩阵,表明了第I个小组分配J台机器生产的魔法石能量。 输出 输出所有小组能产生的最大魔法石能量和 。 样例输入 3 3 30 40 50 20 30 50 20 25 30 样例输出 70 分析:dp[i][j]表示前i个公司分配j台机器最大盈利,MAP[i][j]表示第i个公司分配j台机器的盈利,状态转移方程为:dp[i][j]=max(dp[i-1][k]+MAP[i][j-k],dp[i][j]) #include <iostream> #include < string > #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include

【动态规划】超级教主

匿名 (未验证) 提交于 2019-12-03 00:42:01
问题 I: 【动态规划】超级教主 问题 I: 【动态规划】超级教主 时间限制: 内存限制: 64 MB 提交: 解决: 85 [ 提交 ] [ ״̬ ] [ 讨论版 ] [命题人: ] 题目描述 教主很能跳,因为Orz他的人太多了。教主跳需要消耗能量,每跳1米就会消耗1点能量,如果教主有很多能量就能跳很高。 教主为了收集能量,来到了一个神秘的地方,这个地方凡人是进不来的。在这里,教主的正上方每100米处就有一个能量球(也就是这些能量球位于海拔100,200,300……米处),每个能量球所能提供的能量是不同的,一共有N个能量球(也就是最后一个能量球在N×100米处)。教主为了想收集能量,想跳着吃完所有的能量球。教主可以自由控制他每次跳的高度,接着他跳起把这个高度以下的能量球都吃了,他便能获得能量球内的能量,接着吃到的能量球消失。教主不会轻功,教主不会二段跳,所以教主不能因新吃到的能量而变化此次跳跃的高度。并且教主还是生活在地球上的,所以教主每次跳完都会掉下来。 问教主若要吃完所有的能量球,最多还能保留多少能量。 输入 输入的第1行包含两个正整数N,M,表示了能量球的个数和教主的初始能量。 第2行包含N个非负整数,从左到右第I个数字依次从下向上描述了位于I×100米位置能量球包含的能量,整数之间用空格隔开。 输出 输出仅包括一个非负整数,为教主吃完所有能量球后最多保留的能量。 样例输入

【动态规划】货币系统问题

匿名 (未验证) 提交于 2019-12-03 00:42:01
【动态规划】货币系统问题 时间限制: 内存限制: 64 MB 提交: 解决: 62 [ 提交 ] [ ״̬ ] [ 讨论版 ] [命题人: ] 题目描述 输入 第一行为两个整数V和N,V是货币种类数目,1≤V≤25,N是要构造的面值,1≤N≤1000。 第二行为V种货币的面值。 输出 输出方案数。 样例输入 3 10 1 2 5 样例输出 10 分析:这题好像做过。。具体参考之前的一个货币题。。 #include <iostream> #include < string > #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <deque> #include <map> #define range(i,a,b) for(int i=a;i<=b;++i) #define LL long long #define rerange(i,a,b) for(int i=a;i>=b;--i) #define fill(arr,tmp) memset(arr,tmp,sizeof(arr)) using namespace std; int n,m,aa[ 30 ],dp[ 1005 ]; void init

《算法导论》动态规划―最优二分搜索树

匿名 (未验证) 提交于 2019-12-03 00:41:02
?假如我们现在在设计一个英文翻译程序,要把英文翻译成汉语,显然我们需要知道每个单词对应的汉语意思。我们可以建立一颗二分搜索树来实现英语到汉语的关联。为了更快速地翻译,我们可以使用AVL树或者红黑树使每次查询的时间复杂度Θ(lgn),实际上对于字典翻译程序来说这么做存在一个问题,比如“the”这个单词经常用,却很有可能存在于十分远离树根的位置,而“machicolation”这种不常用的单词很可能存在于十分靠近树根的位置,这就导致查询频率高的单词需要的查询时间更长,而查询频率很低的单词查询时间却很短。这明显不符合我们的期望,我们希望高频率的单词用更少的时间查询到,低频率的单词则用相对更长的时间查询到,也就是高频单词靠近树根,而低频单词远离树根。这时,我们就需要一颗最优二分搜索树来解决这个问题。 给定一个组长度为n关键字的有序序列K=< k1, k2, k3 ・・・・ kn > 以及对应关键字的出现概率P=< p1, p2, p3 ・・・・ pn > 由于我们要检索的关键字可能不在树中,所以我们需要n+1个伪关键字 给定一组长度为n+1的伪关键字D=< d0, d1, d2 ・・・・ dn > 其中d0表示小于任何一个关键字的值,dn表示大于任何一个关键字的值,当 i != 0 && i != n 时,di 表示所有大于ki且小于ki+1的不存在于序列K中的值的集合(不考虑值相等的情况

动态规划Leetcode 746 Min Cost Climbing Stairs

匿名 (未验证) 提交于 2019-12-03 00:38:01
Leetcode 746 Min Cost Climbing Stairs Problem Description: 爬楼梯:一次可以爬1-2层楼梯,每爬一层楼梯会消耗对应的能量,求出爬到最高一层的楼梯时所消耗的最少能量。 具体的题目信息: https://leetcode.com/problems/min-cost-climbing-stairs/description/ Example: Solution: class Solution { public : int minCostClimbingStairs ( vector < int > & cost ) { if ( cost . size () == 2 ) return cost [ 1 ]; int a = 0 , b = 0 ; for ( int i = 0 ; i < cost . size (); i ++) { int t = min ( a , b )+ cost [ i ]; a = b ; b = t ; } return min ( a , b ); } }; 转载请标明出处: 动态规划Leetcode 746 Min Cost Climbing Stairs 文章来源: 动态规划Leetcode 746 Min Cost Climbing Stairs

动态规划之合唱团问题

匿名 (未验证) 提交于 2019-12-03 00:34:01
#include<iostream> #include <math.h> #include <limits.h> #include<algorithm> using namespace std; int main() { int studentNum; cin>>studentNum; int *energyNum=new int[studentNum]; for(int i=0;i<studentNum;i++) { cin>>energyNum[i]; } int k; int d; cin>>k>>d; long long int **maxF=new long long int*[k+1]; long long int **minF=new long long int*[k+1]; for(int i=0;i<k+1;i++) { maxF[i]=new long long int[studentNum]; minF[i]=new long long int[studentNum]; for(int j=0;j<studentNum;j++) { maxF[i][j]=0; minF[i][j]=0; } } for(int i=0;i<studentNum;i++) { maxF[1][i]=energyNum[i]; minF[1][i]=energyNum[i]; }