zoukankan      html  css  js  c++  java
  • 蓝桥杯-PREV28-地宫取宝

    先自己用dp解了一遍,然后看了官方讲解视频是用记忆化搜索做的。感觉那位老师的方法比较容易实现(效率上和我的差不多的);记录一下三种方法。

    • 动态规划
      地宫取宝 1.195KB C++ 正确 100 15ms 1.113MB
      #include "bits/stdc++.h"
      using namespace std;
      const int MOD = 1000000007;
      // mp是地宫地图,table[i][j]表示从坐标(1, 1)走到(i, j)的方案数 
      int mp[55][55], table[55][55];
      // dp[i][j][k]表示在坐标(i, j)手中有k件物品的方案数 
      int dp[55][55][15];
      int main() {
          int n, m, k;
          scanf("%d%d%d", &n, &m, &k);
          table[1][1] = 1;
          for (int i = 1; i <= n; i++)
          for (int j = 1; j <= m; j++)
          if (i != 1 || j != 1)
          table[i][j] = table[i - 1][j] + table[i][j - 1];
          for (int i = 1; i <= n; i++)
          for (int j = 1; j <= m; j++)
          scanf("%d", &mp[i][j]);
          for (int i = 1; i <= n; i++)
          for (int j = 1; j <= m; j++) {
              dp[i][j][1] = table[i][j];
              for (int x = i; x <= n; x++)
              for (int y = j; y <= m; y++) {
                  // dp[x][y][z]是从dp[i][j][z - 1]推出来的;
                  // 要乘(i, j)到(x, y)的方案数; 把(i, j)看做(1, 1)就相当于乘table[x - i + 1][y - j + 1] 
                  for (int z = 2; z <= k; z++)
                  if (mp[x][y] > mp[i][j]) 
                  dp[x][y][z] = (dp[x][y][z] + dp[i][j][z - 1] * 1LL * table[x - i + 1][y - j + 1]) % MOD ;
              }
          }
          int res = 0;
          for (int i = 1; i <= n; i++)
          for (int j = 1; j <= m; j++)  
          res = (res + dp[i][j][k] * 1LL * table[n - i + 1][m - j + 1]) % MOD;
          printf("%d
      ", res);
          return 0;
      } 
    • 深度优先搜索
      地宫取宝 734B C++ 运行超时 42 运行超时 952.0KB
      #include "bits/stdc++.h"
      using namespace std;
      const int MOD = 1000000007;
      int mp[55][55];
      int n, m, k;
      int dfs(int x, int y, int mx, int cnt) {
          if (x > n || y > m || cnt > k) {
              return 0;
          }
          if (x == n && y == m) {
              if (cnt == k || (cnt == k - 1 && mx < mp[x][y])) {
                  return 1;
              }
              return 0;
          }
          int res = 0;
          if (mp[x][y] > mx) {
              res = (res + dfs(x + 1, y, mp[x][y], cnt + 1)) % MOD;
              res = (res + dfs(x, y + 1, mp[x][y], cnt + 1)) % MOD;
          }
          res = (res + dfs(x + 1, y, mx, cnt)) % MOD;
          res = (res + dfs(x, y + 1, mx, cnt)) % MOD;
          return res;
      }
      int main() {
          scanf("%d%d%d", &n, &m, &k);
          for (int i = 1; i <= n; i++)
          for (int j = 1; j <= m; j++)
          scanf("%d", &mp[i][j]);
          printf("%d
      ", dfs(1, 1, -1, 0));
          return 0;
      }

       七组数据过了三组

    • 记忆化搜索
      地宫取宝 0.995KB C++ 正确 100 0ms 3.535MB
      #include "bits/stdc++.h"
      using namespace std;
      const int MOD = 1000000007;
      int mp[55][55];
      int dp[55][55][15][15];
      int n, m, k;
      int dfs(int x, int y, int mx, int cnt) {
          if (x > n || y > m || cnt > k) {
              return 0;
          }
          // 因为mx可能为-1,所以这里mx + 1,后面的mx + 1也是一样 
          if (dp[x][y][mx + 1][cnt] != -1) {
              return dp[x][y][mx + 1][cnt];
          }
          if (x == n && y == m) {
              if (cnt == k || (cnt == k - 1 && mx < mp[x][y])) {
                  dp[x][y][mx + 1][cnt] = 1;
                  return 1;
              }
              dp[x][y][mx + 1][cnt] = 0;
              return 0;
          }
          int res = 0;
          if (mp[x][y] > mx) {
              res = (res + dfs(x + 1, y, mp[x][y], cnt + 1)) % MOD;
              res = (res + dfs(x, y + 1, mp[x][y], cnt + 1)) % MOD;
          }
          res = (res + dfs(x + 1, y, mx, cnt)) % MOD;
          res = (res + dfs(x, y + 1, mx, cnt)) % MOD;
          dp[x][y][mx + 1][cnt] = res;
          return res;
      }
      int main() {
          scanf("%d%d%d", &n, &m, &k);
          for (int i = 1; i <= n; i++)
          for (int j = 1; j <= m; j++)
          scanf("%d", &mp[i][j]);
          memset(dp, -1, sizeof(dp));
          printf("%d
      ", dfs(1, 1, -1, 0));
          return 0;
      }
  • 相关阅读:
    css
    js
    css3
    css
    深浅拷贝
    index-数据结构/算法
    es6知识点
    在vscode中配置sass savepath
    计算机基础
    element-ui使用后手记
  • 原文地址:https://www.cnblogs.com/Angel-Demon/p/10474865.html
Copyright © 2011-2022 走看看