http://www.bnuoj.com/problem_show.php?pid=12976
參考:
https://blog.csdn.net/u013008291/article/details/47972041
狀態轉移方程:
dp[s|1<<j][j] = min(dp[s|1<<j][j],dp[s][i]+ dis(i,j) );
code:
#include <iostream>
#include <stdio.h>
#include <string>
#include <typeinfo>
#include <stack>
#include <vector>
#include <sstream>
#include <string.h>
#include <map>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
typedef long long LL;
char G[20][20];
int dp[1<<16][16];
struct point{
int x,y;
}p[16];
int goldcnt = 0;
int dis(int i,int j){
point p1 = p[i];
point p2 = p[j];
return max(abs(p1.x-p2.x),abs(p1.y-p2.y));
}
int cal(){
memset(dp,0x3f,sizeof(dp));
dp[0][goldcnt-1] = 0;
for(int s = 0 ;s < (1<<goldcnt);s++){
for(int i = 0;i < goldcnt ;i++){
for(int j = 0;j< goldcnt ;j++){
if(!(s&(1<<j) )){
dp[s|1<<j][j] = min(dp[s|1<<j][j],dp[s][i]+ dis(i,j) );
}
}
}
}
return dp[ (1<<goldcnt)-1 ][goldcnt-1];
}
int main()
{
int T;
scanf("%d",&T);
int m,n;
for(int ca = 1;ca<=T;ca++){
int ret = 0;
int sx,sy;
goldcnt = 0;
scanf("%d%d",&m,&n);
for(int i=0;i<m;i++){
scanf("%s",G[i]);
for(int j=0;j<n;j++){
if(G[i][j]=='g'){
p[goldcnt].x = i;
p[goldcnt].y = j;
goldcnt++;
}else if(G[i][j]=='x'){
sx = i;
sy = j;
}
}
}
p[goldcnt].x = sx;
p[goldcnt].y = sy;
goldcnt ++;
cout<<"Case "<<ca<<": "<<cal()<<endl;
}
return 0;
}