1057 - Collecting Gold
Time Limit: 2 second(s) Memory Limit: 32 MB

Finally you found the city of Gold. As you are fond of gold, you start collecting them. But there are so much gold that you are getting tired collecting them.

So, you want to find the minimum effort to collect all the gold.

You can describe the city as a 2D grid, where your initial position is marked by an 'x'. An empty place will be denoted by a '.'. And the cells which contain gold will be denoted by 'g'. In each move you can go to all 8 adjacent places inside the city.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case will start with a blank line and two integers, m and n (0 < m, n < 20) denoting the row and columns of the city respectively. Each of the next m lines will contain n characters describing the city. There will be exactly one 'x' in the city and at most 15 gold positions.

Output

For each case of input you have to print the case number and the minimum steps you have to take to collect all the gold and go back to 'x'.

Sample Input

Output for Sample Input

2

5 5

x....

g....

g....

.....

g....

5 5

x....

g....

g....

.....

.....

Case 1: 8

Case 2: 4

思路:状态压缩dp;

一开始用状压搜索来写的wa;

这题是个状态压缩dp,dp[i][j],表示在状态i下到j结束的最小的花费,将起始点放入一起状压,因为起点也是终点,那么最后答案就是dp[(1<<cn)-1][cn-1];cn为起始的标号,也是点的个数

还有可以8个方向,那么两个点的最小距离就是x,y两个方向距离中大的那个;

  1. 1 #include<stdio.h>
  2. 2 #include<algorithm>
  3. 3 #include<stdlib.h>
  4. 4 #include<iostream>
  5. 5 #include<math.h>
  6. 6 #include<string.h>
  7. 7 #include<queue>
  8. 8 using namespace std;
  9. 9 typedef long long LL;
  10. 10 char ma[22][22];
  11. 11 int __ma[22][22];
  12. 12 int dp[1<<16][22];
  13. 13 typedef struct node
  14. 14 {
  15. 15 int x;
  16. 16 int y;
  17. 17 } ss;
  18. 18 ss ans[100];
  19. 19 int d(int n,int m,int nn,int mm)
  20. 20 {
  21. 21 int x = abs(n-nn);
  22. 22 int y = abs(m-mm);
  23. 23 return max(x,y);
  24. 24 }
  25. 25 int main(void)
  26. 26 {
  27. 27 int n,m;
  28. 28 int T,__ca=0;
  29. 29 scanf("%d",&T);
  30. 30 while(T--)
  31. 31 {
  32. 32 __ca++;
  33. 33 int i ,j;
  34. 34 //memset(flag,0,sizeof(flag));
  35. 35 scanf("%d %d",&n,&m);
  36. 36 for(i = 0; i < n; i++)
  37. 37 {
  38. 38 scanf("%s",ma[i]);
  39. 39 }
  40. 40 int __n,__m;
  41. 41 int cn=0;
  42. 42 for(i = 0; i < n; i++)
  43. 43 {
  44. 44 for(j = 0; j < m; j++)
  45. 45 {
  46. 46 if(ma[i][j] == 'x')
  47. 47 {
  48. 48 __n=i;
  49. 49 __m=j;
  50. 50 }
  51. 51 if(ma[i][j]=='g')
  52. 52 {
  53. 53 ans[cn].x = i;
  54. 54 ans[cn].y = j;
  55. 55 __ma[i][j] = cn++;
  56. 56 }
  57. 57 }
  58. 58 }
  59. 59 int ask=0;
  60. 60 for(i = 0; i < (1<<16); i++)
  61. 61 {
  62. 62 for(j = 0; j < 16; j++)
  63. 63 {
  64. 64 dp[i][j] = 1e9;
  65. 65 }
  66. 66 }
  67. 67 ans[cn].x = __n;
  68. 68 ans[cn].y = __m;
  69. 69 __ma[__n][__m] = cn++;
  70. 70 dp[0|(1<<(cn-1))][cn-1] = 0;
  71. 71 if( cn != 1)
  72. 72 {
  73. 73 for( i = 0; i <(1<<cn); i++)
  74. 74 {
  75. 75 for(int x = 0; x < cn; x++)
  76. 76 { if(i & (1<<x))
  77. 77 for(int y = 0; y < cn; y++)
  78. 78 {
  79. 79 int di=d(ans[x].x,ans[x].y,ans[y].x,ans[y].y);
  80. 80 dp[i|(1<<y)][y] = min(dp[i|(1<<y)][y],dp[i][x]+di);
  81. 81 }
  82. 82 }
  83. 83 }
  84. 84 ask=dp[(1<<cn)-1][cn-1];
  85. 85 }
  86. 86 printf("Case %d: ",__ca);
  87. 87 printf("%d\n",ask);
  88. 88 }
  89. 89 return 0;
  90. 90 }

1057 - Collecting Gold的更多相关文章

  1. lightoj 1057 - Collecting Gold(状压dp)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1057 题解:看似有点下记忆话搜索但是由于他是能走8个方向的也就是说两点的距离其 ...

  2. 1057 - Collecting Gold (状态压缩DP)

    题目大意: 给你一个矩阵,'x'是你的起始位置, 'g'是宝藏的位置,问最少多少步可以把所有的宝藏取完,并且最后返回起始位置. 注意:没有宝藏的时候输出 0   =================== ...

  3. lightoj1057 - Collecting Gold (tsp问题)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1057 题目大意:在二维矩阵中,给你一个起点和至多15个的目标点.要你求出从起点出发经过 ...

  4. LightOJ1057 Collecting Gold(状压DP)

    这道题可以想到几点: 整个行程可以看作一次次的行走,每次行走都是用最短的路程从某一非空点到达另外一非空点: 两点间最少的步数是二者x和y坐标差的最大值: 返回原点这个过程,肯定是取完最后一个黄金后直接 ...

  5. LeetCode 1219. Path with Maximum Gold

    原题链接在这里:https://leetcode.com/problems/path-with-maximum-gold/ 题目: In a gold mine grid of size m * n, ...

  6. 【leetcode】1219. Path with Maximum Gold

    题目如下: In a gold mine grid of size m * n, each cell in this mine has an integer representing the amou ...

  7. POJ2096 Collecting Bugs

    Time Limit: 10000MS   Memory Limit: 64000K Total Submissions: 5090   Accepted: 2529 Case Time Limit: ...

  8. 【BZOJ-3039&1057】玉蟾宫&棋盘制作 悬线法

    3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 753  Solved: 444[Submit][Status][Discuss] D ...

  9. 【poj2096】Collecting Bugs

    题目描述 Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other materia ...

随机推荐

  1. HTML 基本标签2

    HTML标题通过<h1>-<h6>标签定义(<h1>定义最大的标题,<h6>定义最小的标题) <html>用于定义HTML文档 HTML段落 ...

  2. Netty之Channel*

    Netty之Channel* 本文内容主要参考**<<Netty In Action>> ** 和Netty的文档和源码,偏笔记向. 先简略了解一下ChannelPipelin ...

  3. Activity 详解

    1.活动的生命周期 1.1.返回栈 Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称作返回栈.栈是一种先进后出的数据结构,在默认情况下,每当我们启 ...

  4. SpringBoot的定时任务

    springBoot定时任务可分为多线程和单线程,而单线程又分为注解形式,接口形式 1.基于注解形式 基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影 ...

  5. Next_day()函数的用法

    一.定义 NEXT_DAY(date,char)  date参数为日期型,  char:为1~7或Monday/Mon~Sunday/    指定时间的下一个星期几(由char指定)所在的日期,  c ...

  6. 【C/C++】BanGDream活动点数计算器

    作为一个白嫖咸鱼,我每个活动都只打出三星卡就不玩了,于是写了一个模拟器,算算还要打几把hhh #include <iostream> #include <algorithm> ...

  7. 【C/C++】算法入门:排序/算法笔记

    (设排序从小到大) 冒泡排序 这个大家都会,从第一个开始往后俩俩交换,然后第二个,最后到最后一个,复杂度n^2 选择排序 思路和冒泡差不多,比如要得到从小到大的排序,就是从第一个开始,i取1~n,每次 ...

  8. Go modules基础精进,六大核心概念全解析(上)

    点击一键订阅<云荐大咖>专栏,获取官方推荐精品内容,学技术不迷路! Go 语言做开发时,路径是如何定义的?Go Mudules又为此带来了哪些改变?本文将会全面介绍Go modules六大 ...

  9. 「Python实用秘技02」给Python函数定“闹钟”

    本文完整示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/PythonPracticalSkills 这是我的系列文章「Python实用秘技」的第2期 ...

  10. git push大文件失败(write error: Broken pipe)完美解决

    问题 在使用git push推送大文件(超过了100MB)到GitHub远程仓库时提示异常,异常信息如下: fatal: sha1 file '<stdout>' write error: ...