• 1057


    题目大意:
    给你一个矩阵,'x'是你的起始位置, 'g'是宝藏的位置,问最少多少步可以把所有的宝藏取完,并且最后返回起始位置。
    注意:没有宝藏的时候输出 0
     
    ====================================================================================
     
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<map>
    using namespace std;
    typedef long long LL;
    const int INF = 1e9+7;
    const int MAXN = 40000;
    int dp[MAXN][20], m, n, k;///状态,当前所在的位置
    char maps[30][30];
    struct Point
    {
        int x, y;
    }P[20], Star;
    
    int GetLen(Point A, Point B)
    {
        int len = min(abs(A.x-B.x),abs(A.y-B.y));
        len += max(abs(A.x-B.x),abs(A.y-B.y)) - len;
        return len;
    }
    
    int DFS(int sta,int x)///状态, 现在所在的位置
    {
        if(dp[sta][x] != -1) return dp[sta][x];
    
        dp[sta][x] = INF;
        for(int i=0; i<k; i++)
        {
            if( (sta&(1<<i)) && i != x)
            {
                dp[sta][x] = min(dp[sta][x], DFS(sta-(1<<x), i)+GetLen(P[x],P[i]));
            }
        }
       // printf("dp[%d][%d] = %d
    ", sta, x, dp[sta][x]);
        return dp[sta][x];
    }
    
    
    int main()
    {
        int T, cas = 1;
        scanf("%d", &T);
        while(T --)
        {
            scanf("%d %d",&n, &m);
            k = 0;
            memset(dp, -1, sizeof(dp));
            for(int i=0; i<n; i++)
            {
                scanf("%s", maps[i]);
                for(int j=0; j<m; j++)
                {
                    if(maps[i][j] == 'g')
                        P[k].x = i, P[k++].y = j;
                    if(maps[i][j] == 'x')
                        Star.x = i, Star.y = j;
                }
            }
    
            for(int i=0; i<k; i++)
            {
                int sta = 1<<i;
                dp[sta][i] =  GetLen(Star, P[i]);
            }
    
            int ans = INF, Lim = (1<<k)-1;
            for(int i=0; i<k; i++)///最后停留的位置
                ans = min(ans,DFS(Lim,i)+GetLen(Star,P[i]));
            if(k == 0)
                ans = 0;
            printf("Case %d: %d
    ", cas ++, ans);
        }
        return 0;
    }
  • 相关阅读:
    Apache Tomcat开机后台启动
    android res文件夹下面的 values-v11 、 values-v14
    view.performClick()触发点击事件
    android Java BASE64编码和解码一:基础
    Android 正则表达式
    Android 中的Json解析工具fastjson 、序列化、反序列化
    Android 5中不同效果的Toast
    Android 中的编码与解码
    Android Http请求框架二:xUtils 框架网络请求
    Android-Universal-Image-Loader 框架使用
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4919494.html
Copyright © 2020-2023  润新知