零点看书 > 无人驾驶帝国 > 第一百九十二章 道路游戏

第一百九十二章 道路游戏


  星期二下午,驾驶学科奥赛培训。

  沈笑夫才知道,江岸市第一职业中学一年级参加驾驶学科奥赛培训的共有20人。

  王老师亲自上课。首先让大家自我介绍,互相认识了一下。

  20个同学,男生占了15个,女生仅仅5个,少得可怜!

  沈笑夫翻阅《高中组驾驶学科奥赛基础知识》,觉得比初中组难了不少。

  王老师说,今天学习的是程序——《道路游戏》。

  【题目描述】

  小新正在玩一个简单的电脑道路游戏。

  游戏中有一条环形马路,马路上有  n  个机器人工厂,两个相邻机器人工厂之间由一小段马路连接。

  小新以某个机器人工厂为起点,按顺时针顺序依次将这  n  个机器人工厂编号为1~n,因为马路是环形的,所以第  n  个机器人工厂和第  1  个机器人工厂是由一段马路连接在一起的。

  小新将连接机器人工厂的这  n  段马路也编号为  1~n,并规定第  i  段马路连接第  i  个机器人工厂和第  i+1个机器人工厂(1≤i≤n-1),第  n  段马路连接第n个机器人工厂和第  1个机器人工厂。

  游戏过程中,每个单位时间内,每段马路上都会出现一些金币,金币的数量会随着时间发生变化,即不同单位时间内同一段马路上出现的金币数量可能是不同的。

  小新需要机器人的帮助才能收集到马路上的金币。

  所需的机器人必须在机器人工厂用一些金币来购买,机器人一旦被购买,便会沿着环形马路按顺时针方向一直行走,在每个单位时间内行走一次,即从当前所在的机器人工厂到达相邻的下一个机器人工厂,并将经过的马路上的所有金币收集给小新。

  例如,小新在  i(1≤i≤n)号机器人工厂购买了一个机器人,这个机器人会从  i  号机器人工厂开始,顺时针在马路上行走,第一次行走会经过  i  号马路,到达  i+1  号机器人工厂(如果  i=n,机器人会到达第  1  个机器人工厂),并将  i  号马路上的所有金币收集给小新。

  游戏中,环形马路上不能同时存在2个或者2个以上的机器人,并且每个机器人最多能够在环形马路上行走  p次。

  小新购买机器人的同时,需要给这个机器人设定行走次数,行走次数可以为  1~p  之间的任意整数。当马路上的机器人行走完规定的次数之后会自动消失,小新必须立刻在任意一个机器人工厂中购买一个新的机器人,并给新的机器人设定新的行走次数。

  以下是游戏的一些补充说明:

  游戏从小新第一次购买机器人开始计时。

  购买机器人和设定机器人的行走次数是瞬间完成的,不需要花费时间。

  购买机器人和机器人行走是两个独立的过程,机器人行走时不能购买机器人,购买完机器人并且设定机器人行走次数之后机器人才能行走。

  在同一个机器人工厂购买机器人的花费是相同的,但是在不同机器人工厂购买机器人的花费不一定相同。

  购买机器人花费的金币,在游戏结束时再从小新收集的金币中扣除,所以在游戏过程中小新不用担心因金币不足,无法购买机器人而导致游戏无法进行。也因为如此,游戏结束后,收集的金币数量可能为负。

  现在已知每段马路上每个单位时间内出现的金币数量和在每个机器人工厂购买机器人需要的花费,请你告诉小新,经过  m  个单位时间后,扣除购买机器人的花费,小新最多能收集到多少金币。

  【输入输出格式】

  【输入格式】

  第一行  3  个正整数,n,m,p,意义如题目所述。

  接下来的n  行,每行有m个正整数,每两个整数之间用一个空格隔开,其中第  i  行描

  述了  i  号马路上每个单位时间内出现的金币数量(1≤金币数量≤100),即第i行的第  j(1≤j≤m)个数表示第  j  个单位时间内i号马路上出现的金币数量。

  最后一行,有  n  个整数,每两个整数之间用一个空格隔开,其中第  i  个数表示在  i  号机器人工厂购买机器人需要花费的金币数量(1≤金币数量≤100)。

  【输出格式】

  共一行,包含  1  个整数,表示在  m  个单位时间内,扣除购买机器人花费的金币之后,小新最多能收集到多少金币。

  【思路】

  用一维数组f储存第i秒能获得的最大钱数

  因为最多同时存在1个机器人

  第i秒时第j个机器人走k次(1<=k<=p)

  f[i]=max(f[i],f[i-k]-pay[last]+sum)

  这里是从当前点倒推

  last是上一个点

  当last=0,last=n

  sum要一遍遍加上钱k秒第last路上的金币数

  每次减去第last条道路(即第last个工厂机器人)的价格

  如果i-k<0

  直接退出k循环,时间不为负

  【代码】

  #include<iostream>

  #include<cstdio>

  #include<cstring>

  using  namespace  std;

  int  n,m,p,b[1001],a[1001][1001],f[1001];

  int  main()

  {

    scanf(“%d%d%d“,&n,&m,&p);

    memset(f,-1000000,sizeof(f));  f[0]=0;

    for(int  i=1;i<=n;i++)  for(int  j=1;j<=m;j++)  scanf(“%d“,&a[i][j]);

    for(int  i=1;i<=n;i++)  scanf(“%d“,&b[i]);

    for(int  i=1;i<=m;i++)

    for(int  j=1;j<=n;j++)

  {

    int  t=j-1;

    if(!t)  t=n;

    int  ss=a[t][i];

    for(int  k=1;k<=p;k++)

  {

    if(i-k<0)  break;

    f[i]=max(f[i],f[i-k]+ss-b[t]);

    t--;

    if(!t)  t=n;

    ss+=a[t][i-k];

  }

  }

    printf(“%d“,f[m]);

    return  0;

  }

  【数据范围】

  对于  40%的数据,2≤n≤40,1≤m≤40。

  对于  90%的数据,2≤n≤200,1≤m≤200。

  对于  100%的数据,2≤n≤1000,1≤m≤1000,1≤p≤m。

  【做法说明】

  题目呢,比较长,信息比较多,注意不要看错题。但是呢还是比较轻易可以看出这是dp题的类型。

  dp[i][j]表示时间i在j点的最大收益,pre[j]表示j点的上一个,mx[i]表示在时间i所有位置的最大收益(因为买机器人是任意位置可买,转移时直接用即可),g[i][j]表示状态(i,j)取最优解时走的步数(这个明显是越小越好啦),最后输出max(dp[m][i])。

  王老师说:“高中驾驶学科奥赛,要更多地运用到数学与信息学的知识,请大家有机会课外都多补一补这方面的知识。”

  沈笑夫心里一阵咯噔,数学和信息学,要加油啊!

  这时,坐在旁边的一个男生对沈笑夫说:“沈笑夫,我是汽车三班的刘李阳,请多关照!”

  沈笑夫侧目一看,这个男生脸色白净,头发新潮,一脸虔诚地看着自己。

  沈笑夫点点头说:“互相关照!”

  “有你这个大佬罩着,我心里有谱了,呵呵!”刘李阳笑着说。

  ……

  下课后,沈笑夫眼前出现了驾驶学科奥赛系统显示屏:

  学科:  L1,288/1000

   体能:  L1,97/100

  情绪:  L1,89/100

  任务:  0

  奖励:奖励记忆胶囊一粒。请点击“兑奖”键领取奖励。

  学科、奖励栏的背景亮着光,说明这两项有了变化!其他栏目背景灰暗,说明没有变化。

  学科栏从284到288,增加了4个点,是这几天学习驾驶学科知识的收获。

  奖励栏再次出现久违的记忆胶囊!

  沈笑夫有些鸡冻,轻轻点击“兑奖”键,屏幕里立马滚出一粒蓝色的记忆胶囊!

  好!

  记忆胶囊在手,复杂的信息学,也就容易了!

  麻烦的数学,也不会那么麻烦了!

  沈笑夫嘴角露出了开森的笑容!


  https://www.lingdianksw8.com/87/87780/555155013.html


  天才一秒记住本站地址:www.lingdianksw8.com。零点看书手机版阅读网址:m.lingdianksw8.com