ROB机器人采样

一、题目描述:机器人R在一个有n×n个方格区域F中收集样本。(i,j)方格中样本的

价值为v(i,j),如图所示,R从方形区域F的左上角A点出发,向下或向右行走,直到右

下角的B点,在走过的路上,收集方格中的样本。RA点到B点共走2次,试找出R

2条行走路径,使其取得的样本总价值最大。

二、题目分析

性质1:机器人RA点走到B点的一条路径的方格数为2*n-1

 

证明:A点的坐标是(11),B点的坐标是Bn, n),从A点走到B点,按照向下或向右行走的规则,则A必须向下和向左各跨n-1个方格,再加上原来在起点(11)的那个方格,所以A点走到B点的一条路径的方格数为 2*n-1+1=2*n-1;

 

性质2:记机器人R的当前坐标是NX,Y),从起点A到当前点N的路径方格数是Steps,则有Steps=X+Y1

 

证明:因为AN的坐标分别为(11)和(X,Y,所以从起点AN向下走的步数和是X-1,向右走的步数和是Y-1再加上原来在起点(11)的那个方格,则从起点A到当前点N的路径方格数为: X-1+Y-1+1=X+Y-1

 

三、题目解答

此题可用动态规划解答,机器人走的步数将问题划分为2*n-1个状态,题目要求RAB共走两次,如果分两次来走的话,一个就是效率低下问题,另一个就是难以标记那些点是在第一次已经走过,对重复走两次的点所造成的误差难以消除。有个办法就是同时走两条路径,当两条路径走到相同一点时,只对相同点取值一次。由性质2我们知道,在一定的Steps的情况下,如果知道当前点的X轴坐标,就可以知道Y轴坐标Y=StepsX+1,所以可以记M[Steps][x1][x2]为两条路径同时走Steps步的情况下,到达(x1y1(x2,y2)所取的当前最大值。由于机器人只能向下和向左走,那么在(x1y1(x2,y2)的前一个状态就是一下四种之一:

x1y1-1(x2,y2-1)

x1y1-1(x2-1,y2)

x1-1y1(x2-1,y2)

x1-1y1(x2,y2-1)

当(x1y1(x2,y2)是不同点的情况下,状态转移方程如下:

       M[Steps][x1][x2]=max{M[steps-1][x1][x2]+v[x1][y1]+v[x2][y2],

                                             M[steps-1][x1][x2-1]+v[x1][y1]+v[x2][y2],

                           M[steps-1][x1-1][x2]+v[x1][y1]+v[x2][y2],

                           M[steps-1][x1-1][x2-1]+v[x1][y1]+v[x2][y2]}

当(x1y1(x2,y2)是相同点的情况下,状态转移方程如下:

       M[Steps][x1][x2]=max{M[steps-1][x1][x2]+v[x1][y1]

                                             M[steps-1][x1][x2-1]+v[x1][y1]

                           M[steps-1][x1-1][x2]+v[x1][y1]

                           M[steps-1][x1-1][x2-1]+v[x1][y1] }

实现代码如下:

 

#include<iostream>

using namespace std;

#define Max_n 50

#define Max_s 2*50-1

int M[Max_s][Max_n][Max_n];

int v[Max_n][Max_n];

int max(int a,int b)

{

      return a>b?a:b;

}

void MaxValue(int steps,int x1,int x2,int &value)

{

    int y1=steps+1-x1;

    int y2=steps+1-x2;

    if(x1==x2)

      value=max( M[steps][x1][x2]+v[x1][y1],value);

    else

      value=max( M[steps][x1][x2]+v[x1][y1]+v[x2][y2],value);

}

 

int main()

{

    int n;//图的规模

    int nodes;//图中有值的点的个数

    int value,steps;//

    cin>>n>>nodes;

    memset(M,0,sizeof(M));

    memset(v,0,sizeof(v));

    for(int i=0;i<nodes;i++)

    {

       int c,r,val;

       cin>>c>>r>>value;

       v[c][r]=val;

    }

    M[1][1][1]=v[1][1];

   for(steps=2;steps<=2*n-1;steps++)

      for(int x1=1;x1<=steps;x1++)

         for(int x2=1;x2<=steps;x2++)

         {

              value=0;

              MaxValue(steps-1,x1,x2,value);

                MaxValue(steps-1,x1,x2-1,value);

                MaxValue(steps-1,x1-1,x2,value);

                MaxValue(steps-1,x1-1,x2-1,value);

                M[steps][x1][x2]=value;

          }

    cout<<M[2*n-1][n][n]<<endl;

  //  system("pause");

}

以上代码经过GC++ 调试,

样题输入样例:

8

2 3 13

2 6 6

3 5 7

4 4 14

5 2 21

5 6 4

6 3 15

7 2 14

 

输出:

67

 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值