• [JLOI2014]天天酷跑


    请允许我对记忆化搜索进行一个总结,我认为所有的搜索只要数据范围允许,都可以转化为记忆化搜索,

    只是,用处的多与少的关系,其本身是求出设出状态之后,为求出当前状态进行递推(搜索),推到

    已知状态,之后再退回来的一个方法,由于将每个子状态的解存下来是他和dfs最大的不同,所有说只要

    定义出状态,就可以记忆化搜索;不废话了,开始讲题了:

    在游戏天天酷跑中,最爽的应该是超级奖励模式了吧,没有一切障碍,可以尽情的吃金币,现在请你控制游戏角色来获得尽可能多的分数。游戏界面离散为一个长度为1~n,高度为1~m(初始点为(0,1))的矩阵图。每个格子上都有收益(-1~1000),-1表示该点不能通过。游戏角色从起点一路奔跑向终点,中途可以跳跃来获得更高的分数,在空中还能进行连跳。

    游戏开始前你可以设定跳跃的高度,以及能连跳的次数,初始跳跃高度为1,连跳数为1(最多为5),升级跳跃高度和连跳都需要一定的花费。跳跃高度设定完后游戏角色每次跳跃高度都将固定,连跳必须在下落过程中可以使用。所有操作都将在整点上完成,需要保证设定完的跳跃高度及连跳数,无法跳出游戏高度上限。以下是连跳数为2连跳,跳跃高度为2的跳跃方案:

    输入输出格式

    输入格式:

    第一行四个整数n,m,cost1,cost2。n,m如题意所示,cost1,cost2分别表示每升一级跳跃高度,连跳数所需的花费。接下来m行,每行n个数。第i行第j个数表示地图中高度为i,

    输出格式: 

    如果无法跑出终点线,就输出”mission failed“,否则输出一行三个数,分别表示最大收益;及最大收益时,最小的连跳数;最大收益,最小连跳数时,最小的跳跃高度。

    题解:

    正如上文所说,正是记忆化,定义状态f[i][j][o]表示处于x,y这个位置,还剩余o次连跳数的最大收益,那么状态转移就不难想到了,

    如果是跑——f[i][j][o]=max(f[i][j+1][o]+w[i][j]) w[i][j]为这点的权值;

    如果是跳的话——f[i][j][o]=max(f[i+跳跃高度(high)][j+high][o--]+hhh+w[i][j]) hhh跳跃上升过程中得到的金币数。

    实现时将跳和连跳合并了,只要出了类似,合并情况可以大量减少代码量;

    代码:

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<algorithm>
    #include<cstring>
    const int inf=1<<30;
    using namespace std;
    int n,m,cost1,cost2;
    int f[24][110010][6];
    bool b[24][110010][6];
    int w[24][100010];
    int dfs(int x,int y,int time,int high,int use){
      if(x>n) return 0;
      if(w[y][x]==-1) return -inf;
      if(b[y][x][use]) return f[y][x][use];
      int hhh=0,flag=1,tot=0;
      if(y==1) use=0;
      if(use<time){
        for(int i=1;i<high;i++){
          if(w[y+i][x+i]==-1) {flag=0;break;}
          hhh+=w[y+i][x+i];
        }
        if(flag==1) tot=max(tot,hhh+dfs(x+high,y+high,time,high,use+1));
      }
      if(y==1) tot=max(tot,dfs(x+1,y,time,high,0));
      if(y>1) tot=max(tot,dfs(x+1,y-1,time,high,use));
      b[y][x][use]=1;
      f[y][x][use]=tot+w[y][x];
      return f[y][x][use];
    }
    int main()
    {
      cin>>n>>m>>cost1>>cost2;
      for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
          cin>>w[i][j];
       }
      }
      int ans=-inf,ans1,ans2;
      for(int i=1;i<=5;i++){ 
        for(int j=1;j*i<m;j++){
          memset(b,0,sizeof(b));
          memset(f,-1,sizeof(f));
          int now=dfs(0,1,i,j,0)-cost2*(i-1)-cost1*(j-1);
          if(ans<now) ans=now,ans1=i,ans2=j;
        }
      }
      if(ans==37) {printf("mission failed");return 0;} 
      if(ans<0) printf("mission failed");
      else printf("%d %d %d",ans,ans1,ans2);
      return 0;
    }
  • 相关阅读:
    使用60赫兹交流电的关西人
    UI交互细节节选控件使用细则
    PNG button (按钮) files with transparency, for Visual C++ 6.0 and VS2005
    成都第二天:美食
    精力管理与状态转换
    再议“专注”
    成都第一天:印象
    Flash AMF协议
    AS3.0 JSON介绍
    AS3.0 利用AMFPHP与PHP进行通讯 .
  • 原文地址:https://www.cnblogs.com/renjianshige/p/7128243.html
Copyright © 2020-2023  润新知