[关闭]
@LIUHUAN 2020-01-20T00:39:09.000000Z 字数 2739 阅读 667

骑士走键盘

algorithm


骑士在键盘上走日形状的个数

next= { 
        {0:{4, 6}}
        {1:{6, 8 }}
        {2:{7, 9 }}
        {3:{4, 8 }}
        {4:{0, 3, 9 }}
        {5:{ }  }
        {6:{0, 1, 7 }}
        {7:{2, 6}}
        {8:{1, 3}}
        {9:{2, 4}}
\}


方法一:递归

  1. unordered_map<int, vector<int>> umap;
  2. const int M = int(1e9 + 7);
  3. int knightDialer(int N)
  4. {
  5. umap[0] = { 4, 6 };
  6. umap[1] = { 6, 8 };
  7. umap[2] = { 7, 9 };
  8. umap[3] = { 4, 8 };
  9. umap[4] = { 0, 3, 9 };
  10. umap[5] = {};
  11. umap[6] = { 0, 1, 7 };
  12. umap[7] = { 2, 6 };
  13. umap[8] = { 1, 3 };
  14. umap[9] = { 2, 4 };
  15. int c = 0;
  16. for (int i = 0; i < 10; i++) {
  17. c += knight(i, 1, N);
  18. c %= M;
  19. }
  20. return c;
  21. }
  22. int knight(int k, int step, int n)
  23. {
  24. if (step == n)
  25. return 1;
  26. auto list = umap[k];
  27. int size = list.size();
  28. int s = 0;
  29. for (int i = 0; i < size; i++) {
  30. int x = knight(list[i], step + 1, n);
  31. s += x % M;
  32. s %= M;
  33. }
  34. return s % M;
  35. }

方法二:转化为备忘录递归(自顶向下的方法)

  1. unordered_map<int, vector<int>> umap;
  2. unordered_map<string, int> cache;
  3. const int M = int(1e9 + 7);
  4. int knightDialer(int N)
  5. {
  6. umap.clear();
  7. cache.clear();
  8. umap[0] = { 4, 6 };
  9. umap[1] = { 6, 8 };
  10. umap[2] = { 7, 9 };
  11. umap[3] = { 4, 8 };
  12. umap[4] = { 0, 3, 9 };
  13. umap[5] = {};
  14. umap[6] = { 0, 1, 7 };
  15. umap[7] = { 2, 6 };
  16. umap[8] = { 1, 3 };
  17. umap[9] = { 2, 4 };
  18. int c = 0;
  19. for (int i = 0; i < 10; i++) {
  20. c += knight(i, 1, N);
  21. c %= M;
  22. }
  23. return c;
  24. }
  25. int knight(int k, int step, int n)
  26. {
  27. if (step == n)
  28. return 1;
  29. string key = to_string(k) + "-" + to_string(step);
  30. if (cache.find(key) != cache.end()) {
  31. return cache[key];
  32. }
  33. auto list = umap[k];
  34. int size = list.size();
  35. int s = 0;
  36. for (int i = 0; i < size; i++) {
  37. int x = knight(list[i], step + 1, n);
  38. s += x % M;
  39. s %= M;
  40. }
  41. cache[key] = s % M;
  42. return cache[key];
  43. }

方法三:转化为备忘录递归(自底向上的方法)(转化为迭代计算)

  1. unordered_map<int, vector<int>> umap;
  2. const int M = int(1e9 + 7);
  3. int knightDialer(int N){
  4. umap[0] = { 4, 6 };
  5. umap[1] = { 6, 8 };
  6. umap[2] = { 7, 9 };
  7. umap[3] = { 4, 8 };
  8. umap[4] = { 0, 3, 9 };
  9. umap[5] = {};
  10. umap[6] = { 0, 1, 7 };
  11. umap[7] = { 2, 6 };
  12. umap[8] = { 1, 3 };
  13. umap[9] = { 2, 4 };
  14. int c = 0;
  15. int size = 10;
  16. vector<vector<int>> dp(size, vector<int>(N, 0));
  17. // base case #1
  18. for (int i = 0; i < size; i++) {
  19. dp[i][0] = 1;
  20. }
  21. for (int s = 1; s < N; s++) {
  22. for (int i = 0; i < size; i++) {
  23. auto next = umap[i];
  24. for (auto e : next) { //
  25. dp[i][s] += dp[e][s - 1];
  26. dp[i][s] %= M;
  27. }
  28. }
  29. }
  30. for (int i = 0; i < size; i++) {
  31. c += dp[i][N - 1];
  32. c %= M;
  33. }
  34. return c % M;
  35. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注