C++之动态规划复习
来源:互联网 发布:c语言基础教程pdf 编辑:程序博客网 时间:2024/06/07 11:15
C++之动态规划总复习
声明:这些题只讲思路,若有需求,可在评论回复。
【基础算法】 书的复制
时间限制: 1 Sec
内存限制: 64 MB
题目描述
现在要把m本有顺序的书分给k个人复制(抄写),每一个人的抄写速度都一样,一本书不允许给两个(或以上)的人抄写,分给每一个人的书,必须是连续的,比如不能把第一、第三、第四本书给同一个人抄写。 现在请你设计一种方案,使得复制时间最短。复制时间为抄写页数最多的人用去的时间。
输入
第一行两个整数m,k;(k≤m≤500) 第二行m个整数,第i个整数表示第i本书的页数。
输出
共k行,每行两个整数,第i行表示第i个人抄写的书的起始编号和终止编号。k行的起始编号应该从小到大排列,如果有多解,则尽可能让前面的人少抄写。
样例输入
9 31 2 3 4 5 6 7 8 9
样例输出
1 56 78 9
分析
因为题目中提到’m本有顺序的书分给k个人’,所以,我们可以设f[i][j]表示的是:把j本书分给i个人抄写所需的最短时间。值得注意的是:每个DP的这种数组都需要赋值。那赋值为什么呢?其实,在题目中我们不难发现:有一个值一定是固定的——一个人抄j本书的时间。由此,我们可以得到f[1][j]的初值了(0-0 需要输入)。而不是f[1][j]的数的初始值就为10000000(极大值),因为在题目中我们有看到’复制时间’最短,而它也要进行比较,自然取最大的。(便于比较,不会出错)和谁比较?自然是左边和右边。如图;即状态转移方程式为:f[k][m]=min{max{f[k-1][i],d[j]-d[l]},f[i][j]}.
k=2;① ①1 | 2 3 4 5 6 7 8 91 2 | 3 4 5 6 7 8 91 2 3 | 4 5 6 7 8 9 1 2 3 4 | 5 6 7 8 9 ....1 2 3 4 5 6 7 8 | 9 k=3;② ①1 2 | 3 4 5 6 7 8 91 2 3 | 4 5 6 7 8 9 1 2 3 4 | 5 6 7 8 9 ....1 2 3 4 5 6 7 8 | 9 k=4;③ ①1 2 3 | 4 5 6 7 8 9 1 2 3 4 | 5 6 7 8 9 ....1 2 3 4 5 6 7 8 | 9
而至于最后的输出方案数,我们可以用贪心的方法来实现(当然,也可以用二分来实现)。因为我们已经求得用时(最优值T),所以第k个人,他们每个人最多T页。所以从最后一本书开始逆序分配给k个人抄写(尽可能让前面的人少抄写)。然后是k-1,k-2……
【基础算法】挖地雷
题目描述
在一个地图上有N个地窖,依次编号为1..N,每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。
例如在下图中:
上图表示,地窖1可以挖到地窖2,地窖3;地窖2可以挖到地窖4;地窖3可以挖到地窖4,地窖5;地窖4可以挖到地窖5. 当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着某条路径接着往下挖(仅能选择一条路径),当某个地窖无连接时挖地雷工作结束。
试设计一个挖地雷的方案,使某人能挖到最多的地雷。
输入
第1行:1个整数N(1<=N<=20),表示地窖的个数
第2行:N个用空格分开的整数,第i个整数表示地窖i里所埋的地雷个数
第3行~N+1行:第i+2行有n-i个用空格分开的整数,第i+2行描述第i个地窖与第i+1,i+2,…,n个地窖的连接情况。某个整数为1,表示有路径相连,为0,表示无路径相连。
输出
第1行:1个整数,表示能挖到的最多的地雷数量
第2行:若干个用空格分开的整数,表示所挖的地窖编号。编号按所挖地窖的顺序输出,若有多个方案都得到最多的地雷数量,则输出编号尽可能小的一组。
样例输入
510 8 4 7 61 1 0 00 1 01 1 1
样例输出
311 2 4 5
题目分析
其实,这道题目可以从后往前去看(不要问我为什么)。如此,则边界为f[n]=w[n],w[i]为第i个地窖所藏有的地雷数,a[i][j]表示第i地窖与第j个地窖是否有通路,f[i]为从第i个地窖开始最多可以挖出的地雷数。在我看来,其实这道题就是一个最长上升子序列的改版。我们不难发现,文题中的最大地雷数可以看做最长长度。由此,我们便可以以相同的方法来完成此题。但是,值得注意的是,我们在寻找f[j]后的最大地雷数时,还需要判断这条路走不走得通。
【NOIP2000提高】乘积最大
时间限制: 1 Sec
内存限制: 64 MB
题目描述
今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:
设有一个长度N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大。
同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:有一个数字串: 312,当N=3,K=1时会有以下两种分法: 1)3*12=36 2)31*2=62 这时,符合题目要求的结果是: 31*2=62
现在,请你帮助你的好朋友XZ设计一个程序,求得正确的答案。
输入
第1行:共有2个自然数N,K (6<=N<=40,1<=K<=6)
第2行:一个长度为N的数字串
输出
第1行:最大乘积
样例输入
4 21231
样例输出
62
提示
注意数据规模,答案可能会超过int范围
题目分析
面对此题,我们可以用它插入的乘号数来划分阶段,即插入k个乘号,可看做k个阶段的决策的问题。设f[i][k]表示在前i位数中插入k个乘号的最大值,a[i][j]表示从i位到j位所组成的自然数。即可得:f[i][k]=max{f[j][k-1]*a[j+1][i]} (k<=j)(j<i
)边界值为:f[j][0]=a[1][j].
【基础算法】0-1背包问题
时间限制: 1 Sec
内存限制: 64 MB
题目描述
有 n 件物品, 每件物品有一个价值和一个重量,分别记为: b1,b2, …bn w1,w2, …wn 其中所有的 重量wi 均为整数。 现有一个背包,其最大载重量为W,要求从这n件物品中任取若干件(这些物品要么被装入要么被留下)。问背包中装入哪些物品可使得所装物品的价值和最大?
输入
第1行:2个整数n(1<=n<=1000)和W(1<=W<=10000),分别表示物品的件数和背包的最大载重量。
第2-n+1行:每行2个用空格分开的整数,第i+1行的整数表示第i件物品的重量wi和价值bi(1<=bi,wi<=10000)。
输出
第1行:1个整数,表示背包所能装下的物品的最大总价值。
第2-?行:每行3个用空格分开的整数,i, wi, bi,分别表示最优解中的物品的编号、重量和价值。
样例输入
4 52 33 44 55 6
样例输出
71 2 32 3 4
题目分析
虽说这道题是一道简单的DP题,但我们还是要拿来说一说。(毕竟它还是挺经典的呢)。在这里,我们可以设f[i][v]表示前i件物品,总重量不超过v的最优价值。则f[i][v]=max{f[i-1][v-w[i]]+c[i],f[i-1][v]},如此,则f[n][m]为最优解。但这样的做法还是有问题,万一它的数据再大一点呢?所以,滚动数组就出现了。我们可以设f[v]为不超过v斤的最大价值。则f[v]=max{f[v],f[v-w[i]]+c[i]}(当v>=w[i],i<=i<=n时)。
【基础算法】硬币问题
时间限制: 1 Sec
内存限制: 64 MB
题目描述
有N种硬币,面值分别为V1,V2,…,Vn。每种都有无限多。给定非负整数S,可以选用多少个硬币,使得面值之和恰好为S?输出硬币数目的最大值和最小值。
输入
第1行:2个整数N(1<=N<=100, 0 <=S <= 10000)
第2行:N个空格分开的整数,表示每种硬币的面值。(1 <= Vi <= S) 数据保证所有的Vi均不相同。
输出
第1行:1个整数,表示币值之和恰好为S的硬币数目的最大值。如果不能达到S,输出-1。
第2行:1个整数,表示币值之和恰好为S的硬币数目的最小值。如果不能达到S,输出-1。
样例输入
2 103 8
样例输出
-1-1
题目分析
这道题,是一道典型的完全背包问题。
口水都干了,直接上代码。
#include<bits/stdc++.h> using namespace std; int f1[10005],f2[10005],a[101]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=0;i<=m;i++){f2[i]=100000;f1[i]=-100000;} f1[0]=0;f2[0]=0; for(int i=1;i<=n;i++) for(int j=0;j<=m;j++) if(a[i]<=j) { f1[j]=max(f1[j],f1[j-a[i]]+1); f2[j]=min(f2[j],f2[j-a[i]]+1); } if(f1[m]<0||f2[m]<0)printf("-1\n-1\n"); else printf("%d\n%d\n",f1[m],f2[m]); }
我们大家一定要有信心,我们一定能看懂的。-__-,好啦,先就这样,后面还会陆续复习的。也希望同学们都要养成复习的习惯喔。
- C++之动态规划复习
- 算法复习之动态规划_03
- 动态规划复习
- 动态规划复习
- 算法复习:动态规划算法
- 【状态压缩】【动态规划】状压DP复习
- 华为so-胜负猜想 动态规划复习
- [NOIP复习]第三章:动态规划
- [WC 2015复习](五)动态规划
- 动态规划 Problem C
- CF374/C(动态规划)
- 【C++】动态规划
- 动态规划C
- C语言实现之三角形问题(非动态规划方法)
- 算法导论 之 动态规划 - 装配线调度问题[C语言]
- 动态规划之0-1背包问题(C实现)
- 动态规划之背包问题(C语言)
- 动态规划之树形动态规划
- retrofit的基本使用(1)
- C语言基础-NULL和0的区别及结构体初始化问题
- 静态内部类
- guava cache 汇总
- illegalArgumentException
- C++之动态规划复习
- ubuntu 14.04系统安装 Scientific Toolworks Understand 软件教程
- js获取元素样式嵌入css样式
- 使用 IBM Data Studio 管理数据库最佳实践
- Laravel之文件上传
- 一般笔试输入的处理
- NKOJ1633 神仙开山【变进制数状压DP】
- linux:使用seq命令产生数字序列
- 关于孚心科技软件FOHEART MotionVenusV1.3.0