其实后来想了一下,这两个题其实是一样的,只不过1044需要剪枝,并且随时需要在结束的时候更新总的值,而且在到达终点的时候不能退出。
1044 代码,看有人用状态压缩,用了900ms,我在队列push之前多添加一个剪枝,就是看当前到终点的距离时候超过了要求的时间,可以降到800ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define maxn 51
using namespace std;
int n,m,l,cnt,ans;
int sx,sy,ex,ey;
int a[15];
int dx[]= {-1,1,0,0};
int dy[]= {0,0,-1,1};
bool vis[maxn][maxn][1<<10];
char s[maxn];
char mp[maxn][maxn];
struct Node
{
int x,y,step,val;
int state;
} cur,now;
queue<Node>q;
bool bfs()
{
int i,j,nx,ny,tx,ty,nstep,nval,nst,tst,tmp;
int head=0,tail=-1;
memset(vis,0,sizeof(vis));
while(!q.empty()) q.pop();
ans=-1;
cur.x=sx;
cur.y=sy;
cur.step=0;
cur.val=0;
cur.state=0;
q.push(cur);
vis[sx][sy][0]=1;
while(!q.empty())
{
now=q.front();
q.pop();
nx=now.x;
ny=now.y;
nstep=now.step;
nval=now.val;
nst=now.state;
if(nstep>l) break ; // 注意退出条件
if(nx==ex&&ny==ey) // 更新ans
{
if(ans<nval) ans=nval;
}
for(i=0; i<4; i++)
{
tst=nst;
tx=nx+dx[i];
ty=ny+dy[i];
cur.val=nval;
if(mp[tx][ty]>='A'&&mp[tx][ty]<='J')
{
tmp=mp[tx][ty]-'A';
if(!(tst&(1<<tmp))) cur.val+=a[tmp]; // 同一珠宝不能拿两次
tst=tst|(1<<tmp);
}
if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&mp[tx][ty]!='*'&&!vis[tx][ty][tst])
{
vis[tx][ty][tst]=1;
cur.x=tx;
cur.y=ty;
cur.step=nstep+1;
cur.state=tst;
if(abs(l-cur.step)>=(abs(ex-cur.x)+abs(ey-cur.y)))
q.push(cur);
}
}
}
if(ans==-1) return false ;
return true ;
}
int main()
{
int i,j,t,t1=0;
scanf("%d",&t);
while(t--)
{
t1++;
scanf("%d%d%d%d",&m,&n,&l,&cnt);
for(i=0; i<cnt; i++)
{
scanf("%d",&a[i]);
}
for(i=1; i<=n; i++)
{
scanf("%s",s);
for(j=1; j<=m; j++)
{
mp[i][j]=s[j-1];
if(s[j-1]=='@')
{
sx=i;
sy=j;
}
if(s[j-1]=='<')
{
ex=i;
ey=j;
}
}
}
if(t1>1) printf("\n");
printf("Case %d:\n",t1);
if(bfs()) printf("The best score is %d.\n",ans);
else printf("Impossible\n");
}
return 0;
}
1072相比来说就简单多了,没有那么多复杂的条件,
将带有重置装置的值置0,其实跟上边那个所谓的状态压缩是同一个东西:
# include <cstdio>
# include <cstring>
# include <iostream>
# include <queue>
using namespace std;
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
struct node
{
int tim,step,x,y;
};
queue<node> que;
int main()
{
int T,i,j,n,m,map[20][20];
node ip,id;
cin>>T;
while(T--)
{
cin>>n>>m;
while(!que.empty()) que.pop();
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
cin>>map[i][j];
if(map[i][j]==2)
{
ip.x=i;
ip.y=j;
ip.step=0;
ip.tim=6;
que.push(ip);
}
}
while(!que.empty())
{
ip=que.front();
que.pop();
if(map[ip.x][ip.y]==3) break;
if(1==ip.tim) continue;
int xx,yy;
for(i=0;i<4;i++)
{
xx=ip.x+dx[i];
yy=ip.y+dy[i];
if(xx>0 && xx<=n && yy>0 && yy<=m && map[xx][yy] )
{
id.tim=ip.tim-1;
if(4==map[xx][yy])
{
id.tim=6;
map[xx][yy]=0;
}
id.x=xx;
id.y=yy;
id.step=ip.step+1;
que.push(id);
}
}
}
if(que.empty()) cout<<"-1"<<endl;
else cout<<ip.step<<endl;
}
return 0;
}