HDU 5025 Saving Tang Monk

没有利用题目所造成的key的特殊性质,结果–比赛的时候和蛇一起状态压缩超内存。
int dp[][][][] -> setdp[][] 试图这样做,减少空间的浪费 结果超时.
用优先队列的搜索到达结果后可直接:

return s.t;

否则应该:

 res=min(res,s.t );

优先列队下可以有这个剪枝

if(s.t<vis[s.x][s.y ][s.s1 ][s.s2 ]){
              continue;
            }

然好像并没有发挥什么作用

#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<iostream>
#include<set>
#include<queue>
using namespace std;
const int INF=0x7fffffff;

//set<int>dp[102][102];
int  vis[102][102][(1<<5)+1][12];
/*struct point{
   int s1,s2;   
}p[(1<<4)*(10)];  根据状态序号可以直接反映射出状态 ,此题无需用到*/
int map2[1<<6][12];
void init(){
    memset(map2,0,sizeof(map2));
    int state_snake=1<<5;
    int state_key=11;
    int cnt=0;
    for(int i=0;i<=state_snake;i++){
        for(int j=0;j<=state_key;j++){
        //  p[cnt].s1 =i;   此题无需用到 
        //  p[cnt].s2 =j;   此题无需用到 
            map2[i][j]=cnt++;
        }
    }
} 
char map1[102][102];
int  idx [102][102];

int  n,m,snake_num;
struct state{
    int x,y,s1,s2,t;
    state(int _x1,int _y1,int _s1,int _s2,int _t):x(_x1),y(_y1),s1(_s1),s2(_s2),t(_t){}
    state(){}
   /* bool operator<(const state& other)  const 
     {
    return t>other.t; 
     }*/                     
};
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};

int find_snake(int i,int j){
   return idx[i][j];
}
int find_key(int i,int j){
   return idx[i][j];
}
int bfs(int kx,int ky){
         int res=INF;
         //queue<state> que;
         priority_queue<state> que;
         while(!que.empty()) que.pop();
     int size1=(1<<snake_num);
        for(int i=0;i<=n;i++){
            for(int j=0;j<=n;j++){
                for(int u=0;u<=size1;u++){
                   for(int v=0;v<=m;v++){
                    vis[i][j][u][v]=-1;
                   }    
                }
            }
        }
         /* for(int i=0;i<=n;i++){
            for(int j=0;j<=n;j++){
              dp[i][j].clear(); 
             }
         } */
         que.push(state(kx,ky,0,0,0));
         dp[kx][ky].insert(map2[0][0]);
         //int kkk=0;
         while(!que.empty()){
            state s=que.top();  que.pop();
         //printf("%d %d %d %d %d \n",kkk++,s.x,s.y ,s.s1 ,s.s2 );

             if(map1[s.x][s.y]=='T' && (s.s2==m) ) {
                 res=min(res,s.t );
                  // return s.t;
             }
                int nx,ny;
                for(int i=0;i<4;i++){

                    nx=s.x +dir[i][0];
                    ny=s.y +dir[i][1];
                    if(nx<0 || nx>=n || ny<0 || ny>=n || map1[nx][ny]=='#')
                    continue;

                    int tmp=s.t;
                    state news=s;
                    news.x =nx,news.y =ny;

                    if(map1[nx][ny]=='S'){
                     int which=find_snake(nx,ny);

                        if((news.s1 &(1<<which) )==0){
                        tmp++;
                        news.s1 |= 1<<which ;
                        }
                    }
                   if(map1[nx][ny]>='1'&&map1[nx][ny]<='9')
                   {
                          int which=find_key(nx,ny);
                          if( news.s2 +1 == which )
                         {
                            news.s2++;
                         }
                   }
                  /* int newid=map2[news.s1][news.s2];
                   if(!dp[news.x ][news.y ].count(newid)){
                       dp[news.x][news.y].insert(newid);
                       que.push(state(news.x ,news.y ,news.s1 ,news.s2,tmp+1));
                   } */

                   if(vis[news.x][news.y][news.s1 ][news.s2 ]==-1){
                      vis[news.x][news.y][news.s1 ][news.s2 ]=tmp+1;
                      que.push(state(news.x ,news.y ,news.s1 ,news.s2,tmp+1));
                   }
                }

         }
         return res;
}


int main(){
         freopen("F:\\123.txt","r",stdin);
    //freopen("D:\\output.txt","r",stdout);
    init();
    while(scanf("%d%d",&n,&m)!=EOF){
      if(n==0&&m==0) break;
      for(int i=0;i<n;i++){
       scanf("%s",map1[i]);
      }
      int kx,ky;
         snake_num=0;

         for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){

              if(map1[i][j]>='0'&&map1[i][j]<='9'){
             idx[i][j]= (int)(map1[i][j]-'0');
              } 
                if(map1[i][j]=='S'){
                    idx[i][j]=snake_num++;
                }
                if(map1[i][j]=='K'){
                    kx=i;ky=j;
                }
             }
         }
        // printf("Looking %d \n",snake_num);
        int res= bfs(kx,ky);
        if(res==INF){
            printf("impossible\n");
        }else{
        printf("%d\n",res);
        }
    }
    return 0;
}

题外话:

struct newdp{
  set<int> s;
}dp[][]   
和
set<int >dp[][] 好像是一样的吧

debug初始的错误

 for(int i=0;i<(1<<6);i++){
            for(int j=0;j<=11;j++){
                dp[i][j].set1.clear();
             }
         }

应该是下面才对

for(int i=0;i<=n;i++){
            for(int j=0;j<=n;j++){
              dp[i][j].clear();
             }
struct state{
    int x,y,s1,s2,t; !!(t一开始没写进去)
    state(int _x1,int _y1,int _s1,int _s2,int _t):x(_x1),y(_y1),s1(_s1),s2(_s2),t(_t){}
    state(){}
   /* bool operator<(const state& other)  const 
     {
    return t>other.t; 
     }*/                     
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值