Title Link: http://acm.fzu.edu.cn/problem.php?pid=2186
Ask Xiao Ming to take all the points containing the treasure to go back to the starting point at least the time required. The first thought is the postman problem, but not. On-line search, see the solution is the pressure DP. Have to look like pressure dp AH.
This is the first pressure DP (looking at someone else's code), is a kind of pressure DP has a certain understanding, through this problem, to talk about their own pressure DP view.
The so-called pressure DP, so the name of the idea is to compress the original state, so that the state of storage becomes concise, reduce the additional state storage. The most commonly used should be the binary method bar, because each data in the computer is stored in the form of binary storage, but also provides a binary operation, so that each state with binary to store or good, such as: State 1001, only need to use 9 to indicate on it.
Freopen ("C:\\Documents and Settings\\All Users\\ desktop \\in.txt", "R", stdin); #include <iostream> #include <cstdio> #include <sstream> #include <cmath> #include <cstring
> #include <algorithm> #include <set> #include <queue> #include <vector> #include <map>
#include <string> #define LL __int64 #define INF 0xfffffff using namespace std;
struct state{int x,y,step;};
int map[110][110],vis[110][110],dis[110][110],x[110],y[110];
int N,m,tot;
int d[][2]={0,1,0,-1,-1,0,1,0};
void BFs (int x,int y,int v) {memset (vis,0,sizeof (VIS));
Queue<state> Q;
Q.push (state) {x,y,0});
Vis[x][y]=1;
int cnt=0; while (!
Q.empty ()) {State tp=q.front ();
if (Cnt==tot) break;
Q.pop ();
for (int p=0;p<4;p++) {int tx=tp.x+d[p][0],ty=tp.y+d[p][1];
if (tx<0 | | ty<0 | | tx>=n | | ty>=m) continue; if (Vis[tx][ty] | | |
MAP[TX][TY]<0) continue; If(map[tx][ty]>0) dis[v][map[tx][ty]]=tp.step+1,cnt++;
Q.push (state) {tx,ty,tp.step+1});
Vis[tx][ty]=1;
}}} int dp[1<<11][13];
int main () {while (cin>>n) {cin>>m;
Tot=1;
for (int i=0;i<n;i++) for (int j=0;j<m;j++) {scanf ("%d", &map[i][j]);
if (i==0 && j==0) continue; if (map[i][j]>0) x[++tot]=i,y[tot]=j,map[i][j]=tot;//point corresponds to coordinate one by one} if (map[0][0]==-1) {cout<<-1< ; <endl;continue;}
Compare pits, actually the initial position can also be-1.
X[1]=0,y[1]=0,map[0][0]=1;
memset (dis,-1,sizeof (dis)); for (int i=1;i<=tot;i++) BFS (x[i],y[i],i);//Find the shortest distance between 22 of the wealth points memset (Dp,-1,sizeof (DP));//Initialize dp[1][0]=0;/ /Initialize for (int i=0;i< (1<<tot); i++)//This is actually the process of DP starting from the initialization state to the backward recursive procedure for (int j=0;j<tot;j++) {//Enumerate the state The end position if (Dp[i][j]==-1 | |
(i& (1<<J)) ==0) continue; for (int k=0;k<tot;k++) {//Add a new point in the original state to go in if (k==j | | dis[j+1][k+1]==-1) continue;//determine if the new point is legitimate int s=i|
(1<<k);//The new state, because it is "|", may actually be the same as I if (dp[s][k]==-1) dp[s][k]=dp[i][j]+dis[j+1][k+1];
else Dp[s][k]=min (dp[s][k],dp[i][j]+dis[j+1][k+1]);
}} cout<<dp[(1<<tot) -1][0]<<endl;
} return 0;
}