- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
动态规划经典题目分析 中山纪念中学 陈启峰 一般步骤 确定状态: 状态的参数一般有 1)描述位置的:前(后)i单位,第i到第j单位,坐标为(i,j)等 2)描述数量的:取i个,不超过i个,至少i个等 3)描述对后有影响的:状态压缩的,一些特殊的性质 一般步骤 转移方程: 1)检查参数是否足够; 2)分情况:最后一次操作的方式,取不取,怎么样放,前一项是什么 3)初始条件是什么。 4)注意无后效性。比如说,求A就要求B,求B就要求C,而求C就要求A,这就不符合无后效性了。 一般步骤 编程实现方式 1)递推 2)记忆化搜索(一般在状态的拓朴顺序不很明确时使用) 一般步骤 恰当地使用数据可以使动态规划的时间复杂度降下。 队列——O(n^2*??)?O(n*??) 线段树、堆、二叉查找树——O(n*??)?O(logn*??) Hash表、并查集——O(n*??)?O(??) 此外运用四边行不等式可以使 O(n^3*??)?O(n^2*??) 经典题 最长公共子序列 最长上升子序列 最优二分检索树 最优矩阵链乘 最优三角剖分 任务调度问题 叠 放 箱 子 【问题】 某港口有一批箱子,将其编号,分别为1至N。每一个箱子的尺寸规格是一样的,现在要将其中某些箱子叠放起来,箱子叠放的规则如下: 一、每个箱子上最多只能直接叠放一个箱子; 二、编号较小的箱子不能放在编号较大的箱子之上; 三、每个箱子都给出了自身重量与可承受重量,每个箱子之上的所有箱子重量之和不得超过该箱的可承受重量。 为了节约堆放场地,希望你编程从中选出最多个箱子,使之能够在满足条件的情况下叠放起来。 【输入】 第一行是一个整数N(1≤N≤1000)。 以下共有N行,每行两个整数,中间以空格分隔,分别表示每个箱子的自身重量与可承受重量,两个数值均为小于等于3000的正整数。 【输出】 第一行应当输出最多可叠放的箱子总数M。 【样例】有五个箱子,如下表: 分析 设F[i,j]表示第i个箱子到第N个箱子中总重量为j的最大箱子数。 考虑第i个箱子放与不放的情况。 注意,能选的条件是 j ≥ weight[i] 并且capacity≥j-weight[i] 代码 program CQF_BOX; uses math; const maxn=1000; var weight,capacity:array[1..maxn] of longint; f:array[1..maxn+1,0..6000] of longint; n:longint; procedure init; var i:longint; begin readln(n); for i:=1 to n do readln(weight[i],capacity[i]); end; procedure work; var i,j,ans:longint; begin fillchar(f,sizeof(f),200); f[n+1,0]:=0; for i:=n downto 1 do for j:=0 to 6000 do begin f[i,j]:=f[i+1,j]; if (j=weight[i])and(capacity[i]=j-weight[i]) then f[i,j]:=max(f[i,j],f[i+1,j-weight[i]]+1); end; ans:=0; for i:=0 to 6000 do ans:=max(ans,f[1,i]); writeln(ans); end; CMI 给出一个1到n的排列,每次可以移动一个数到一个任意位置。问要达到状态1,2,3……n至少移动多少次? Sample Input 5 2 1 4 5 3 Sample Output 2 分析 答案就是N减去这个排列的最长上升子序列的长度lis。 为什么呢? 证明 必要性: 一次移动就相当于删除一个数并添加上这个数。 删除一个数不会增加lis。 添加一个数最多使lis加1。 因此一次移动最多可以使lis加1 要达到目标状态至少要N-lis次移动。 证明 充分性: 每次选取一个非lis上的一个数,并将它移动到lis上合适的位置。也就是说,将它移动到lis上前比它小,后比它大的位置。 算法 运用动态规划: F[i]表示以第i个数为结束的最长上升子序列的长度。 F[i]=max{F[j]+1|value[j]value[i]} 这是O(n^2)的 但是运用BST也可以让算法降到O(nlogn) 还
文档评论(0)