礼物(BFS)

礼物

时间限制: 1 Sec  内存限制: 64 MB
提交: 39  解决: 4
[提交][状态][讨论版]

题目描述

   给出一个n行m列的点阵,“.”表示可通行格子,“#”表示不可通行格子,“K”表示国王的初始位置,“Q”表示王后的位置,“G”表示该格子有一个礼 物。注意:国王、王后、礼物所在的格子可以认为是可通行格子。国王从开始位置出发,国王从当前格子可以走到上、下、左、右四个相邻格子,当然前提是可通行 格子。国王从当前格子走到相邻格子的时间是变化的,这取决于国王手头上收集到的礼物的数量,假如当前国王手头上有y个礼物,那么他从当前格子移动到相邻格 子的所用时间是y+l秒。一旦国王进入某个有礼物的格子,他可以选择取该格子的礼物,也可以选择不取该格子的礼物。取礼物这个动作可以认为是瞬间完成的, 不需要时间。国王想收集到尽量多的礼物送给王后,但是他到达王后所在的格子不能超过T秒,王后不想等太长时间。注意:国王在收集礼物的途中可能多次走到相 同的格子。

输入

  第1行:三个整数n、m、T。 1≤n,m≤50,1≤T≤109。
  接下来是n行m列的点阵,‘G’的数量不超过16。只有一个国王,一个王后。

输出

一个整数,国王在规定时间内,最多可以收集到多少个礼物送给王后?

样例输入

5 7 50
#....G#
###G###
#K...Q#
###.###
#G..GG#

样例输出

4
【分析】威哥写的,表示并不懂,立个flag,日后再学,已经看晕了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#include<functional>
#define mod 1000000007
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int N = (1<<16)+5;
const int INF = 0x3f3f3f3f;
char s[52][52];
int n,m,T;
struct Node {
    int x,y;
    Node(int a=0,int b=0) {
        x=a;
        y=b;
    }
} st,ed;
vector<Node>g;
int d[18][18],dis[51][51],f[N][16];
int dx[4]= {0,0,-1,1};
int dy[4]= {-1,1,0,0};
void bfs(int pos) {
    queue<Node>q;
    memset(dis,INF,sizeof(dis));
    dis[g[pos].x][g[pos].y]=0;
    q.push(g[pos]);
    while(!q.empty()) {
        Node u=q.front();
        q.pop();
        for(int i=0; i<4; ++i) {
            int x=u.x+dx[i],y=u.y+dy[i];
            if(x<1||x>n||y<1||y>m||s[x][y]=='#')continue;
            if(dis[x][y]==INF) {
                dis[x][y]=dis[u.x][u.y]+1;
                q.push(Node(x,y));
            }
        }
    }
    for(int i=0; i<g.size(); ++i)if(i!=pos) {
            d[pos][i]=dis[g[i].x][g[i].y];
        }
}
int main() {
    scanf("%d%d%d",&n,&m,&T);
    for(int i=1; i<=n; ++i)scanf("%s",s[i]+1);
    for(int i=1; i<=n; ++i) {
        for(int j=1; j<=m; ++j) {
            if(s[i][j]=='K')st=Node(i,j);
            else if(s[i][j]=='Q')ed=Node(i,j);
            else if(s[i][j]=='G')g.push_back(Node(i,j));
        }
    }
    g.push_back(st);
    g.push_back(ed);
    memset(d,INF,sizeof(d));
    memset(f,INF,sizeof(f));
    for(int i=0; i<g.size()-1; ++i)bfs(i);
    int ss=g.size()-2,tt=g.size()-1,tot=(1<<(g.size()-2));
    for(int i=0; i<g.size()-2; ++i) {
        f[1<<i][i]=d[ss][i];
    }
    for(int i=1; i<tot; ++i) {
        for(int j=0; j<g.size()-2; ++j) {
            if(!(i&(1<<j))||f[i][j]>=INF)continue;
            for(int k=0; k<g.size()-2; ++k) {
                if((i&(1<<k))||d[j][k]>=INF)continue;
                f[i|(1<<k)][k]=min(f[i][j]+(__builtin_popcount(i)+1)*d[j][k],f[i|(1<<k)][k]);
            }
        }
    }
    int ret=0;
    for(int i=1; i<tot; ++i) {
        for(int j=0; j<g.size()-2; ++j) {
            if(f[i][j]!=INF||d[j][tt]!=INF) {
                int tmp=f[i][j]+(__builtin_popcount(i)+1)*d[j][tt];
                if(tmp<=T) ret=max(ret,__builtin_popcount(i));
            }
        }
    }
    printf("%d
",ret);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/jianrenfang/p/5726244.html