c++动态规划试题+分析
Pascal动态规划-复习

[题2] 数塔
● 如下图所示的数塔,从顶部出发,在每一结点可以选择向左下走或是 向右下走,一直走到底层,要求找出一条路径,使路径上的数的和最 大。数塔层数用n表示,1<=n<=100。
[题2] 数塔
贪心法。时间上有保证,但得不到最优解。主要原因是贪心法只顾 眼前利益,不考虑长远利益。 在规定时间内得到正确结果,唯一的方法就是“动态规划”。
dpl(i,j)=min{dpl(i-1,j)+v(i,j),dpl(i,j-1)+h(i,j)}
[题5] 机器分配
【问题描述】 总公司拥有高效生产设备M台,准备分给下属的N个公司。各分公司
若获得这些设备,可以为国家提供一定的盈利。问:如何分配这M台设
备才能使国家得到的盈利最大?求出最大盈利值。其中M≤15,N≤10。 分配原则:每个公司有权获得任意数目的设备,但总台数不得超过总设
下面以示意图表示动态规划的过程:所选路径为:9-12-10-18-10
注意分析时,有以下几个特点:
(1)将问题划分成了4个阶段;
(2)每个阶段均得到了“部分”的最优解,得到最优解时,需要进行条件判断;
(3)从最下面一层往顶层推导。
[题3] 棋盘路径问题
【题目简介】 有一个n*m的棋盘,左下角为(1,1),右上角为(n,m),如下图: 有一颗棋子,初始位置在(1,1),该棋子只能向右走或者向上走,问该 棋子从(1,1)到(n,m)一共有几条路径? 输入:两个整数n和m 输出:一个数,路径总数
● 第i级台阶,可以从第i-2级台阶迈2级台阶到达,也 可以从第i-1级台阶迈1级台阶到达
上楼梯问题
● 慢在哪里?
● 重叠的问题被计算了多次! ● 例如:计算f[5]时,f[5]=f[3]+f[4];而f[4]=f[3]+f[2], 此时,f[3]又被计算了一遍。 ● 每次计算f[i]时,都要递归到f[0]或f[1]! ● 时间复杂度变成了O(N!)
动态规划算法详解及经典例题

动态规划算法详解及经典例题⼀、基本概念(1)⼀种使⽤多阶段决策过程最优的通⽤⽅法。
(2)动态规划过程是:每次决策依赖于当前状态,⼜随即引起状态的转移。
⼀个决策序列就是在变化的状态中产⽣出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。
假设问题是由交叠的⼦问题所构成,我们就能够⽤动态规划技术来解决它。
⼀般来说,这种⼦问题出⾃对给定问题求解的递推关系中,这个递推关系包括了同样问题的更⼩⼦问题的解。
动态规划法建议,与其对交叠⼦问题⼀次重新的求解,不如把每⼀个较⼩⼦问题仅仅求解⼀次并把结果记录在表中(动态规划也是空间换时间的)。
这样就能够从表中得到原始问题的解。
(3)动态规划经常常使⽤于解决最优化问题,这些问题多表现为多阶段决策。
关于多阶段决策:在实际中,⼈们经常遇到这样⼀类决策问题,即因为过程的特殊性,能够将决策的全过程根据时间或空间划分若⼲个联系的阶段。
⽽在各阶段中。
⼈们都须要作出⽅案的选择。
我们称之为决策。
⽽且当⼀个阶段的决策之后,经常影响到下⼀个阶段的决策,从⽽影响整个过程的活动。
这样,各个阶段所确定的决策就构成⼀个决策序列,常称之为策略。
因为各个阶段可供选择的决策往往不⽌⼀个。
因⽽就可能有很多决策以供选择,这些可供选择的策略构成⼀个集合,我们称之为同意策略集合(简称策略集合)。
每⼀个策略都对应地确定⼀种活动的效果。
我们假定这个效果能够⽤数量来衡量。
因为不同的策略经常导致不同的效果,因此,怎样在同意策略集合中选择⼀个策略,使其在预定的标准下达到最好的效果。
经常是⼈们所关⼼的问题。
我们称这种策略为最优策略,这类问题就称为多阶段决策问题。
(4)多阶段决策问题举例:机器负荷分配问题某种机器能够在⾼低两种不同的负荷下进⾏⽣产。
在⾼负荷下⽣产时。
产品的年产量g和投⼊⽣产的机器数量x的关系为g=g(x),这时的年完善率为a,即假设年初完善机器数为x,到年终时完善的机器数为a*x(0<a<1);在低负荷下⽣产时,产品的年产量h和投⼊⽣产的机器数量y 的关系为h=h(y)。
动态规划-例题众多-详细讲解

步骤2:状态转移方程:
步骤3:以自底向上的方法来计算最优解
12
程序的实现
BuyTicks(T, R)
1 n ← length[T]
2 f[0] ← 0
3 f[1] ← T[1]
4 for i ← 2 to n do
5
f[i] ← f[i-2]+R[i-1]
6
if f[i] > f[i-1]+T[i] then
n 0 1 2 3 4 5 6 7 8 9 10 F(n) 1 1 2 3 5 8 13 21 34 55 89
2
递归 vs 动态规划
递归版本:
F(n)
1 if n=0 or n=1 then
2
return 1
3 else
4
return F(n-1) + F(n-2)
太慢!
动态规划:
F(n)
1 A[0] = A[1] ← 1
这里是某支股票的价格清单: 日期 1 2 3 4 5 6 7 8 9 10 11 12 价格 68 69 54 64 68 64 70 67 78 62 98 87 最优秀的投资者可以购买最多4次股票,可行方案中的一种是: 日期 2 5 6 10 价格 69 68 64 62 输入 第1行: N (1 <= N <= 5000),股票发行天数 第2行: N个数,是每天的股票价格。 输出 输出文件仅一行包含两个数:最大购买次数和拥有最大购买次数的方案数(<=231) 当二种方案“看起来一样”时(就是说它们构成的价格队列一样的时候),这2种方 案被认为是相同的。
你的任务是,已知所有N位同学的身高,计算最少需要 几位同学出列,可以使得剩下的同学排成合唱队形。
动态规划试题

1. 某公司打算向它的三个营业区增设6个销售店,每个营业区至少增设1个。
各营业区每年增加的利润与增设的销售店个数有关,具体关系如表1所示。
试规划各营业区应增设销售店的个数,以使公司总利润增加额最大。
表1解:将问题按区分为三个阶段3,2,1=k ,设状态变量k S (3,2,1=k )代表从第k 个区到第3个区的增设个数,决策变量k x 代表第k 个区的增设个数。
于是有状态转移率k k k x S S -=+1、允许决策集合}0|{)(k k k k k S x x S D ≤≤=和递推关系式:)}()({max )(10k k k k k S x k k x S f x g S f kk -+=+≤≤ )1,2,3(=k0)(44=S f当3=k 时:)}({max }0)({max )(330330333333x g x g S f S x S x ≤≤≤≤=+=于是有表7-2,表中*3x 表示第三个阶段的最优决策。
单位:百万元当2=k 时:)}()({max )(2232202222x S f x g S f S x -+=≤≤于是有表7-3。
表7-3 (单位:百万元)当1=k 时:)}()({max )(1121101111x S f x g S f S x -+=≤≤于是有表7-4。
故最优分配方案为:A 区建3个销售店,B 区建2个销售店,C 区建1个销售店, 总利润为490万元。
2. 某工厂有100台机器,拟分4个周期使用,在每一周期有两种生产任务,据经验把机器投入第一种生产任务,则在一个周期中将有六分之一的机器报废,投入第二种生产任务,则有十分之一的机器报废。
如果投入第一种生产任务每台机器可收益1万元,投入第二种生产任务每台机器可收益0.5万元。
问怎样分配机器在4个周期内的使用才能使总收益最大? 解:阶段:将每个周期作为一个阶段,即k=1,2,3,4 状态变量:第k 阶段的状态变量k S 代表第k 个周期初拥有的完好机器数决策变量:决策变量k x 为第k 周期分配与第一种任务的机器数量,于是k k x S -该周期分配在第二种任务的机器数量。
算法设计与分析-动态规划习题

a
j
k
T(n)=2T(n/2)+O(n) 解此递归方程可知,T(n)=O(nlogn) 3) 记 b[j]=
a
k 1
j
k
,1≤i≤n,则所求的最大子段和问题为
a
k 1
j
k
=max max
a
k i
j
k
=max b[j]
由 b[j]的定义可知,b[j-1]>0 时,b[j]= b[j-1]+a[j], 否则 b[j]=a[j],因此 b[j]的动态规划递 归式 b[j]=max{b[j-1]+a[j],a[j]},1≤j≤n。 据此, 可设计出最大子段和动态规划算法如下: int MaxSum(int n,int *a) { Int sum=0,b=0; For(int i=1;i<=n;i++){ If(b>0)b+=a[j]; Else b=a[j]; If(b>sum)sum=b; } Return sum; } 显然,这个算法需要的时间和空间复杂度均为 O(n)。
则 RELI(1,n,c)可靠性设计的最优值为:
初始条件:f0 (X)=1,0≤X≤c
i
S ={ (f , X ) | f =f (X ) }
i i
S ={ (f , X ) | f =f (X ) }为可靠性设计问题 RELI(1,i,X) 的最优解,(f, X)是由 m1 ,m2 ,…,mi 的
按此递归式计算出来的 m(n,b)为最优值,算法所需的计算时间为 O(nb)。
4、可靠性设计:一个系统由 n 级设备串联而成,为了增强 可靠性,每级都可能并联了不止一台同样的设备。假设第 i 级设备 Di 用了 mi 台,该级设备的可靠性是 gi(mi),则这个 系统的可靠性是Π gi(mi)。一般来说 gi(mi)都是递增函数,所 以每级用的设备越多系统的可靠性越高。但是设备都是有成 本的, 假定设备 Di 的成本是 ci, 设计该系统允许的投资不超 过 c,那么,该如何设计该系统(即各级采用多少设备)使 得这个系统的可靠性最高。试设计一个动态规划算法求解可 靠性设计。
Problem_动态规划01_

长郡中学NOIP动态规划试题01试题名称程序名输入文件输出文件时限空间字串的距离blast. cpp blast.in blast.out 1s 128M 尼克的任务lignja. cpp lignja.in lignja.out 1s 128M1s 128M 数字金字塔numtri.cpp numtri.in numtri.out1s 128M 方格取数 fgqs .cpp fgqs.in fgqs.out1s 128M 多米诺骨牌 dom.cpp dom.in dom.out字符串的距离【问题描述】设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为“abcbcd”,则字符串“abcb□cd”,“□a□bcbcd□”和“abcb□cd□”都是X的扩展串,这里“□”代表空格字符。
如果A1是字符串A的扩展串,B1是字符串B的扩展串,A1与B1具有相同的长度,那么我们定义字符串A1与B1的距离为相应位置上的字符的距离总和,而两个非空格字符的距离定义为它们的ASCII码的差的绝对值,而空格字符与其它任意字符之间的距离为已知的定值K,空格字符与空格字符的距离为O。
在字符串A、B的所有扩展串中,必定存在两个等长的扩展串A1、B1,使得A1与B1之间的距离达到最小,我们将这一距离定义为字符串A、B的距离。
请你写一个程序,求出字符串A、B的距离。
【输入】输入第一行为字符串A,第二行为字符串B,A、B均由小写字母组成且长度均不超过2000,第三行为一个整数K,1≤K≤100,表示空格与其它字符的距离。
【输出】输出仅一行包含一个整数,表示要求的字符串A、B的距离。
【样例】blast.incmcsnmn2blast.out10尼克的任务【问题描述】尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成。
c++经典题目及算法解析

以下是C++中的一些经典题目及其算法解析:1. 两数之和(Two Sum)题目描述:给定一个整数数组nums 和一个目标值target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
算法解析:可以使用哈希表来解决这个问题。
遍历数组,对于每个元素,计算目标和并减去当前元素,得到差值。
在哈希表中查找差值,如果存在则返回下标,否则将当前元素和下标存入哈希表。
2. 三数之和(3Sum)题目描述:给定一个包含n 个整数的数组nums,判断nums 中是否存在三个元素a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
算法解析:可以使用分治法来解决这个问题。
将数组分成A、B、C 三部分,分别求和并记录下标。
对于每个 A 的下标,分别判断 B 和 C 的部分是否存在和为-A 的数对,如果存在则返回结果。
3. 最长回文子串(Longest Palindromic Substring)题目描述:给定一个字符串s,找到s 中最长的回文子串。
你可以假设s 的最大长度为1000。
算法解析:可以使用动态规划来解决这个问题。
定义dp[i][j] 表示s[i..j] 是否为回文串。
根据回文串的性质,如果s[i] = s[j],那么dp[i][j] 一定等于dp[i+1][j-1]。
因此,可以从字符串两端向中间遍历,每次判断两端字符是否相等,如果相等则更新dp 数组,最终找到最长的回文子串。
4. 二分查找(Binary Search)题目描述:给定一个有序数组nums 和一个目标值target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
算法解析:可以使用二分查找来解决这个问题。
定义left 和right 指针指向数组的左右两端,每次比较中间元素和目标值的大小关系,根据比较结果更新左右指针的位置,直到找到目标值或者左右指针相遇。
如果找到了目标值,还需要判断左右指针指向的元素是否相同。
C语言动态规划之背包问题详解

C语⾔动态规划之背包问题详解01背包问题给定n种物品,和⼀个容量为C的背包,物品i的重量是w[i],其价值为v[i]。
问如何选择装⼊背包的物品,使得装⼊背包中的总价值最⼤?(⾯对每个武平,只能有选择拿取或者不拿两种选择,不能选择装⼊某物品的⼀部分,也不能装⼊物品多次)声明⼀个数组f[n][c]的⼆维数组,f[i][j]表⽰在⾯对第i件物品,且背包容量为j时所能获得的最⼤价值。
根据题⽬要求进⾏打表查找相关的边界和规律根据打表列写相关的状态转移⽅程⽤程序实现状态转移⽅程真题演练:⼀个旅⾏者有⼀个最多能装M公⽄的背包,现在有n件物品,它们的重量分别是W1、W2、W3、W4、…、Wn。
它们的价值分别是C1、C3、C2、…、Cn,求旅⾏者能获得最⼤价值。
输⼊描述:第⼀⾏:两个整数,M(背包容量,M<= 200)和N(物品数量,N<=30);第2…N+1⾏:每⾏两个整数Wi,Ci,表⽰每个物品的质量与价值。
输出描述:仅⼀⾏,⼀个数,表⽰最⼤总价值样例:输⼊:10 42 13 34 57 9输出:12解题步骤定义⼀个数组dp[i][j]表⽰容量为j时,拿第i个物品时所能获取的最⼤价值。
按照题⽬要求进⾏打表,列出对应的dp表。
W[i](质量)V[i](价值)01234567891000000000000210011111111133001334444444500135568899790013556991012对于⼀个动态规划问题设置下标时最好从0开始,因为动态规划经常会和上⼀个状态有关系!从上⾯的dp表可以看出来对于⼀个物品我们拿还是不难需要进⾏两步来判断。
第⼀步:判断背包当前的容量j是否⼤于物品当前的质量,如果物品的质量⼤于背包的容量那么就舍弃。
第⼆步:如果背包可以装下这个物品,就需要判断装下该物品获取的最⼤价值是不是⼤于不装下这个物品所获取的最⼤价值,如果⼤于那么就把东西装下!根据这样的思想我们可以得到状态转移⽅程:如果单签背包的容量可以装下物品:dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);如果当前背包的容量装不下该物品:dp[i][j]=dp[i-1][j];#include <stdio.h>int max(const int a,const int b){return a>b ? a:b;}int main(){int w[35]={0},v[35]={0},dp[35][210]={0};int n,m;scanf("%d %d",&m,&n);int i,j;for(i=1;i<=n;i++){scanf("%d %d",&w[i],&v[i]);}for(i=1;i<=n;i++){for(j=1;j<=m;j++){if(j>=w[i])//如果当前背包的容量⼤于商品的质量{dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);//判断是否应该拿下}else//⼤于背包的当前容量{dp[i][j]=dp[i-1][j];}}}for(int k=0;k<=n;k++){for(int l=0;l<=m;l++){printf("%d ",dp[k][l]);}printf("\n");}printf("%d\n",dp[n][m]);}通过运⾏以上程序可以看到最终的输出dp表和我们的预期是相符合的!但是并没有结束,动态规划有⼀个后⽆效性原则(当前状态只与前⼀个状态有关)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
我们设机器人走到(i,j) 位置时拾到最多垃圾数为 f[i][j] ,由于机器人只能朝右和下走, 只 会跟机器人上一位置拾到最多的垃圾数有关,因此很容易写出状态转移方程。 F[i][j]=max{f[i-1][j],f[i][j-1]}+a[i][j],(1<=i<=n,1<=j<=m) 初始值:f[1][i]=f[1][i-1]+a[1][i] ,f[i][1]=f[i-1][1]+a[i][1] 时间复杂度为:O(nm) 我们再来看第二问: 在最优解的情况下求方案总数, 我们只要每次在最优解的情况下统 计路径条数即可,见图 2: 设 g[i][j] 表示在位置(i,j)达到拾到 f[i][j]垃圾时的路径总数,有如下ቤተ መጻሕፍቲ ባይዱ程: g[i][j]=g[i-1][j]*x+g[i][j-1]*y 当 f[i][j]=f[i-1][j]+a[i][j] 时,x=1,否则 x=0; 当 f[i][j]=f[i][j-1]+a[i][j] 时,y=1,否则 y=0;
using namespace std; int n,m,a[200005],b[200005],f[200005]; void init() { int i,j=0; cin>>n>>m; for(i=1;i<=n;i++)cin>>a[i]; for(i=1;i<m;i++)if(a[i]<a[m])b[++j]=a[i];//去掉前面大于等于 a[m]的数 b[++j]=a[m]; for(i=m+1;i<=n;i++)if(a[i]>a[m])b[++j]=a[i];//去掉后面小于等于 a[m]的数 } int ERLIS()//上升子序列 { int i,L,r,mid,len=1; f[1]=b[1]; for(i=2;i<=n;i++) { L=1;r=len; if(f[len]<b[i]){len++;f[len]=b[i];continue;} while(L<=r) { mid=(L+r)/2; if(f[mid]<b[i])L=mid+1;else r=mid-1; } f[L]=b[i]; } return len; } int main() { init(); cout<<ERLIS()<<endl; } 3、采药 .cpp/c/pas) (medic medic.cpp/c/pas) 【问题描述】 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最 有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都 是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间, 每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果 你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。” 如果你是辰辰,你能完成这个任务吗? 【输入格式】 输入文件的第一行包含两个正整数 N,M。M 表示总共能够用来采药的时间,N 代表山 洞里的草药的数目。 接下来的 N 行每行包括两个的整数,分别表示采摘某株草药的时间 T i 和这株草药的价 值 V i。 【输出格式】 输出文件仅包含一个整数表示规定时间内可以采到的草药的最大总价值。 【样例输入输出】 medic .in medic .out medic.in medic.out 39 3 10 10 81 12 】 【数据规模和约定 数据规模和约定】 50%的数据中 N ,M≤1000;
∑
k =i
③设 f[i][j] :表示在前 j 个村庄建立 i 个邮局所得的最小距离和。 f[1][i]=g[1][i]; f[i][j]=min{f[i-1][k]+g[k+1][j]},(2<=i<=m,i<=j<=n,i-1<=k<=j-1) #include<iostream> #include<cstdio> #include<cstring> #include <algorithm> using namespace std; int a[1005],n,m,sum[1005],g[1005][1005],f[1005][1005]; void Init() { int i,j,k,L; //n 个村庄,m 个邮局 cin>>n>>m; cin>>n>>m;//n for(i=1;i<=n;i++)cin>>a[i]; sort(a+1,a+n+1); //先按照距离从小到大快排 for(i=1;i<=n-1;i++) //初始化 g[i][j] { g[i][i]=0; for(j=i+1;j<=n;j++)g[i][j]=g[i][j-1]+abs(a[j]-a[(i+j)/2]); } } void DP() { int i,j,k,Min; for(i=1;i<=n;i++)f[1][i]=g[1][i]; for(i=2;i<=m;i++) //阶段:邮局 for(j=i;j<=n;j++) //状态:村庄 { Min=0x7fffffff/2; for(k=i-1;k<=j-1;k++) if(Min>f[i-1][k]+g[k+1][j])Min=f[i-1][k]+g[k+1][j]; f[i][j]=Min; } cout<<f[m][n]<<endl; } int main() { Init(); DP(); system("pause"); }
100%的数据中 N ,M≤100000,Ti,V i≤10。 【题目考点】01 背包+多重背包 【思路点拨】题面虽然是最直接的 01 背包问题,但根据数据规模只能得 50 分。注意到 T 和 V 都不超不过 10 ,于是物品的种类不会超过 121。于是可以采用多重背包的算法解决该 题。 #include<fstream> using namespace std; ifstream cin("medic.in"); ofstream cout("medic.out"); int N,M,T[105],V[105],amt[105],cnt=0,f[100005],sum[11][11]; void init() { int i,j,t,v; cin>>N>>M; for(i=1;i<=N;i++){cin>>t>>v;sum[t][v]++;}//sum[t][v]时间为 t,价格为 v 的草药数量 for(i=1;i<=10;i++) for(j=1;j<=10;j++) if(sum[i][j]) { amt[++cnt]=sum[i][j];//数量 T[cnt]=i;//时间 V[cnt]=j;//价格 } } void Complete(int v,int t) { for(int i=t;i<=M;i++) if(f[i-t]+v>f[i])f[i]=f[i-t]+v; } void ZeroOne(int v,int t) { for(int i=M;i>=t;i--) if(f[i-t]+v>f[i])f[i]=f[i-t]+v; } void Mult_Pack() { for(int i=1;i<=cnt;i++) { if(amt[i]*T[i]>M){Complete(V[i],T[i]);continue;} int k=1; while(k<=amt[i]) { ZeroOne(V[i]*k,T[i]*k); amt[i]-=k; k*=2; } if(amt[i])ZeroOne(V[i]*amt[i],T[i]*amt[i]); } } int main() { init(); Mult_Pack(); cout<<f[M]<<endl; return 0; }
动态规划模拟试题 5: 10) (时间:1:40—— ——5: 5:1 1、拾垃圾的机器人 (robit.cpp/c/pas) 【问题描述】 有一块地被划分成了 n*m 个区域,在一些区域里有垃圾要拾捡。现在科研人员开发了 一个能捡垃圾的机器人, 机器人每一次都可以移动一个区域的距离, 假设机器人从最左上区 域出发, 他每次只能向右或者向下走。 每次他到达一个点, 就会自动把这个点内的垃圾拾掉。 问:该机器人最多能够拾多少垃圾? 在最多情况下,有多少种方案? 【输入格式】 输入文件的第一行为两个整数 n 和 m; 接下来有一个 n*m 的 01 矩阵。 矩阵中的第 i 行 j 列的数字 a[i][j]=0 表示为空地, a[i][j]=1 表示为垃圾。 【输出格式】 输出文件的第一行为一个整数,表示该机器人拾到的最多垃圾数。 第二行为一个整数,表示该机器人拾到的最多垃圾的路径总数。 【样例输入输出 1】 robit.in robit.out 33 2 100 3 000 010 【样例输入输出 2】 robit.in robit.out 67 5 0101000 11 0001010 0000000 0001001 0000000 0000010 【数据范围】n<=100,m<=100 【思路点拨】我们先看样例,如图 1,垃圾用 G 表示。假设机器人走到(i,j) 这个位置,由于 机器人只能向下向右走,那么机器人的上一个位置一定是(i-1,j)和(i,j-1)。