题意:有一个三维的地图,有n个人被困住,现在消防队员只能从1楼的一个入口进入,营救被困者,每一个被困者有一个价值,当消防队员找到一个被困者之后,他可以营救或者见死不救,如果救的话,他必须马上将其背到入口处,不得停下,不得同时救多个人,而且回去的时间一步要做两步走,即时间增加一倍。求在给定时间S内,能救到的人的最大价值总和。
解法:bfs一遍记录每个点离起点的最短距离,那么救这个人的花费就是3*dis,然后已经知道救这个人的价值,那么最后求一个01背包即可。
要注意一个人都救不到的地方,我开始将dis都初始化为1000000007,这样的话如果走不到的话,花费就变成3*dis爆int了。悲剧。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #include <queue> #define Mod 10000007 using namespace std; #define N 50107 char mp[15][125][125]; int dis[15][125][125]; int dp[10006]; int T[114],P[114],L,H,W; int dx[7] = {0,0,0,0, 1, -1}; int dy[7] = {0,1,-1,0, 0, 0,}; int dz[7] = {1,0,0,-1, 0, 0,}; struct node { int l,h,w,sec; node(int _x,int _y,int _z,int _sec):l(_x),h(_y),w(_z),sec(_sec){} node(){} }vol[135],S; bool OK(int x,int y,int z) { if(x >= 0 && x < L && y >= 0 && y < H && z >= 0 && z < W) return true; return false; } void bfs(node S) { queue<node> q; while(!q.empty()) q.pop(); int i,j,k; for(i=0;i<L;i++) for(j=0;j<H;j++) for(k=0;k<W;k++) dis[i][j][k] = Mod; int x = S.l, y = S.h, z = S.w; dis[x][y][z] = 0; q.push(S); while(!q.empty()) { node now = q.front(); q.pop(); int l = now.l, h = now.h, w = now.w, sec = now.sec; if(mp[l][h][w] == 'U') { for(k=0;k<5;k++) { int nx = l + dx[k]; int ny = h + dy[k]; int nz = w + dz[k]; if(!OK(nx,ny,nz)) continue; if(mp[nx][ny][nz] != 'X') { if(sec+1 < dis[nx][ny][nz]) { dis[nx][ny][nz] = sec+1; node tmp = node(nx,ny,nz,sec+1); q.push(tmp); } } } } else if(mp[l][h][w] == 'D') { for(k=0;k<6;k++) { if(k == 4) continue; int nx = l + dx[k]; int ny = h + dy[k]; int nz = w + dz[k]; if(!OK(nx,ny,nz)) continue; if(mp[nx][ny][nz] != 'X') { if(sec+1 < dis[nx][ny][nz]) { dis[nx][ny][nz] = sec+1; node tmp = node(nx,ny,nz,sec+1); q.push(tmp); } } } } else { for(k=0;k<4;k++) { int nx = l + dx[k]; int ny = h + dy[k]; int nz = w + dz[k]; if(!OK(nx,ny,nz)) continue; if(mp[nx][ny][nz] != 'X') { if(sec+1 < dis[nx][ny][nz]) { dis[nx][ny][nz] = sec+1; node tmp = node(nx,ny,nz,sec+1); q.push(tmp); } } } } } } int main() { int t,n,STime,i,j,k; scanf("%d",&t); while(t--) { scanf("%d%d%d%d%d",&L,&H,&W,&n,&STime); for(i=0;i<L;i++) { for(j=0;j<H;j++) { scanf("%s",mp[i][j]); for(k=0;k<W;k++) if(mp[i][j][k] == 'S') S = node(i,j,k,0); } } for(i=1;i<=n;i++) { scanf("%d%d%d%d",&vol[i].l,&vol[i].h,&vol[i].w,&P[i]); vol[i].l--,vol[i].h--,vol[i].w--; } bfs(S); for(i=1;i<=n;i++) T[i] = 3*dis[vol[i].l][vol[i].h][vol[i].w]; memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { for(j=STime;j>=0;j--) { if(j >= T[i]) dp[j] = max(dp[j],dp[j-T[i]]+P[i]); } } int Maxi = 0; for(i=0;i<=STime;i++) Maxi = max(Maxi,dp[i]); printf("%d\n",Maxi); } return 0; }