• 地宫寻宝


    标题:地宫取宝
        X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。
        地宫的入口在左上角,出口在右下角。
        小明被带到地宫的入口,国王要求他只能向右或向下行走。
        走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
        当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。
        请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。
    【数据格式】
        输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)
        接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值
        要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。
    例如,输入:
    2 2 2
    1 2
    2 1
    程序应该输出:
    2
    再例如,输入:
    2 3 2
    1 2 3
    2 1 5
    程序应该输出:
    14

    资源约定:
    峰值内存消耗 < 256M
    CPU消耗  < 1000ms
    思路:第一样看到都能想到dfs,看到数据范围考虑到要用剪枝,但是题目不仅考虑走的方向,还要考虑每个点要不要把宝藏捡起来,很容易写崩,就算写出来了,还是超时,网上的一种记忆搜索=搜索+dp,很巧妙
    贴出来,以后常回来看看
     1 #include <stdio.h>
     2 
     3 #include <string.h>
     4 
     5 #define N 1000000007
     6 
     7   int n,m,k;
     8 
     9   int map[50][50];
    10 
    11   int dp[50][50][15][15];//dp数组中记录的是状态   xy坐标 拥有宝物数量 拥有宝物的最大值(这4个可以详尽唯一的描述没一种可能) 
    12 
    13                           //如dp[3][4][5][6]=7 即当在map[3][4]且身上有5件宝物 宝物的最大值是6 是到达终点有7中路径
    14 
    15   
    16 
    17   int dfs(int x,int y,int num,int max)//当前位置   拥有宝物的数量 拥有的宝物的最大值
    18 
    19  {
    20 
    21      if (dp[x][y][num][max+1]!=-1)//判断这个状态是否已经走过,如果走过就直接用记录的数值计算//因为宝物有可能为0所以定义max时用最小值-1 这就导致无法作为下标使用  实际上如果测试数据中宝物价值没有0
    22 
    23                                    //将所有的+1 去掉也是可以的   这里的话如果去掉肯定是有些数据不对的,不信可以提交试一下,根本过不了
    24 
    25          return dp[x][y][num][max+1]; 
    26 
    27        //记忆化的记忆就指的是上面
    28 
    29        
    30 
    31      if(x==n&&y==m){//到达出口 
    32 
    33          if( num==k||(num==k-1&&max<map[x][y]) )  //到达右下角,(1)可能不算右下角的也正好,(2)如果右下角的比当前的大,算上这一个如果正好也可以增加路径 
    34 
    35             return dp[x][y][num][max+1]=1;  //满足条件 当前点到目标有1种方案
    36 
    37          else 
    38 
    39          return dp[x][y][num][max+1]=0;//不满足条件 当前点到目标有0种方案
    40 
    41      }
    42 
    43      long long s=0;
    44 
    45      if(x+1<=n){         //可以向下走
    46 
    47          if (max<map[x][y])
    48 
    49              s+=dfs(x+1,y,num+1,map[x][y]);//当前位置   拥有宝物的数量 拥有的宝物的最大值                      
    50 
    51          s+=dfs(x+1,y,num,max);            //当前位置   拥有宝物的数量 拥有的宝物的最大值
    52 
    53      }
    54 
    55      if(y+1<=m){         //可以向右走
    56 
    57          if (max<map[x][y])
    58 
    59              s+=dfs(x,y+1,num+1,map[x][y]);//当前位置   拥有宝物的数量 拥有的宝物的最大值
    60 
    61         s+=dfs(x,y+1,num,max);             //当前位置   拥有宝物的数量 拥有的宝物的最大值
    62 
    63      }
    64 
    65      return dp[x][y][num][max+1]=s%N;
    66 
    67  }
    68 
    69  int main(){
    70 
    71      scanf("%d%d%d",&n,&m,&k);
    72 
    73      for (int i = 1;i<=n;i++)//初始地宫
    74 
    75          for (int j = 1; j <=m; j++)
    76 
    77              scanf("%d",&map[i][j]);
    78 
    79      memset(dp,-1,sizeof(dp));
    80 
    81      dfs(1,1,0,-1);
    82 
    83      printf("%d",dp[1][1][0][0]);
    84 
    85  
    86 
    87      return 0;
    88 
    89  }
  • 相关阅读:
    vue的devTools谷歌插件安装使用
    springcloud(14)seata分布式事务
    springcloud(13)zipkin工具的使用
    springcloud(12)SentinelResource注解配置应用及其他
    springcloud(11)sentinel安装和基本使用
    springcloud(10)Nacos集群(windows环境)
    springcloud(9)Nacos基本操作
    springcloud(8)GateWay网关
    springcloud(7)hystrix服务熔断和dashboard
    通用语言
  • 原文地址:https://www.cnblogs.com/henuliulei/p/10568951.html
Copyright © 2020-2023  润新知