Hdu3681Prison Break状压Dp

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>
using namespace std;
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
int vis[44][44];int dis[44][44];int Hash[1111];int Map[44][44];char str[44][44];
int len;int n,m;int Begin;
int state[1000];
const int INF=0xfffffff;
int dp[1<<17][17];
int Fin;
int Ma(int a,int b)
{
    return a>b?a:b;
}
void bfs(int x,int y)
{
    queue<int > q;
    q.push(x*m+y);
    memset(dis,0,sizeof(dis));
    memset(vis,0,sizeof(vis));
    vis[x][y]=1;dis[x][y]=0;
    while(!q.empty()){
        int cur=q.front();q.pop();
        int xx= cur/m;int yy=cur%m;
        if(~Hash[cur]){
            Map[Hash[x*m+y]][Hash[cur]]= Map[Hash[cur]][Hash[x*m+y]]=dis[xx][yy];
        }
        for(int i=0;i<4;i++){
            int x1=xx+dx[i];int y1=yy+dy[i];
            if(x1>=0&&x1<n&&y1>=0&&y1<m&&!vis[x1][y1]&&str[x1][y1]!=‘D‘){
                vis[x1][y1]=1; dis[x1][y1]=dis[xx][yy]+1;
                q.push(x1*m+y1);
            }
        }
    }
}// 建图

int gao(int mid)
{
    memset(dp,-1,sizeof(dp));
    dp[1<<Begin][Begin] = mid;
    int gg=(1<<len);
    for(int i=0;i<gg;i++){
        for(int j=0;j<len;j++){
            if(dp[i][j]==-1) continue;
            if((i&(1<<j))==0) continue;
            if((i&Fin)==Fin){
                return 1;
            }
            for(int k=0;k<len;k++){
                if((i&(1<<k))) continue;
                if(Map[j][k]==-1||dp[i][j]<Map[j][k]) continue;
                dp[i|(1<<k)][k]=Ma(dp[i|(1<<k)][k],dp[i][j]-Map[j][k]);
                if(state[k]) dp[i|(1<<k)][k]=mid;
            }
        }
    }
    return 0;
} 

int main()
{
    while(cin>>n>>m,n||m){
        memset(state,0,sizeof(state));
        memset(Hash,-1,sizeof(Hash));
        memset(Map,-1,sizeof(Map));
        Fin = 0;len=0;
        for(int i=0;i<n;i++){
            scanf("%s",str[i]);
            for(int j=0;j<m;j++){
                if(str[i][j]==‘S‘||str[i][j]==‘D‘) continue;
                Hash[i*m+j]=len;
                if(str[i][j]==‘F‘) Begin= len,Fin|=(1<<len);
                if(str[i][j]==‘G‘) state[len]=1;
                if(str[i][j]==‘Y‘) Fin|=(1<<len);
                len++;
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
            if(~Hash[i*m+j]){
                bfs(i,j);
            }
        }
        int l = 0;int r=n*m+10;int gg=-1;
        while(l<=r){
            int mid= (l+r)>>1;
            if(gao(mid)){
                gg=mid;r=mid-1;
            }
            else l=mid+1;
        }
        printf("%d\n",gg);
    }
    return 0;
}

Hdu3681Prison Break状压Dp

时间: 2024-11-04 17:57:03

Hdu3681Prison Break状压Dp的相关文章

HDU-3681-Prison Break(BFS+状压DP+二分)

Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one day, the king of Rompire was captured by human beings. His thinking circuit was changed by human and thus became a tyrant. All those who are against him

HDU 3681 Prison Break(bfs+二分+状压DP)

Prison Break Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3778    Accepted Submission(s): 992 Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But on

poj 2411 Mondriaan&#39;s Dream(状压DP)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12232   Accepted: 7142 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series

(状压dp)uva 10817 Headmaster&#39;s Headache

题目地址 1 #include <bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 const int MAX=1e5+5; 5 const int INF=1e9; 6 int s,m,n; 7 int cost[125]; 8 //char sta[MAX]; 9 string sta; 10 int able[125]; 11 int dp[125][1<<8][1<<8]; 12 in

Travel(HDU 4284状压dp)

题意:给n个城市m条路的网图,pp在城市1有一定的钱,想游览这n个城市(包括1),到达一个城市要一定的花费,可以在城市工作赚钱,但前提有工作证(得到有一定的花费),没工作证不能在该城市工作,但可以走,一个城市只能工作一次,问pp是否能游览n个城市回到城市1. 分析:这个题想到杀怪(Survival(ZOJ 2297状压dp) 那个题,也是钱如果小于0就挂了,最后求剩余的最大钱数,先求出最短路和 Hie with the Pie(POJ 3311状压dp) 送披萨那个题相似. #include <

HDU 5765 Bonds(状压DP)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5765 [题目大意] 给出一张图,求每条边在所有边割集中出现的次数. [题解] 利用状压DP,计算不同的连通块,对于每条边,求出两边的联通块的划分方案数,就是对于该点的答案. [代码] #include <cstdio> #include <algorithm> #include <cstring> using namespace std; int n,m,T,Cas=1

BZOJ1087:[SCOI2005]互不侵犯King(状压DP)

[SCOI2005]互不侵犯King Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N) Output 方案数. Sample Input 3 2 Sample Output 16 分析: 经典的状压DP题目,可我竟然调了很长时间都没对,后来发现是DP枚举范围错

poj185--炮兵阵地(状压dp)

炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 20169   Accepted: 7805 Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击

NOJ 1116 哈罗哈的大披萨 【淡蓝】 [状压dp+各种优化]

我只能说,珍爱生命,远离卡常数的题...感谢陈老师和蔡神,没有他们,,,我调一个星期都弄不出来,,,, 哈罗哈的大披萨 [淡蓝] 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 73            测试通过 : 9 描述 热风哈罗哈(三牌楼)店正在搞活动:他们将提供一个大披萨给第一个告诉他们以下信息的人:一次购买任一种披萨,哪种单位面积的价格最低.问题初步想一想,好像是这么解决:“对于每个披萨计算平均