给你一个网格,其中有不多于20家餐厅要预定披萨,披萨店只有一家,这家店有两个外卖员,每次只能送一个披萨。问你送完所有订单所需的最小时间。
一开始没看到只有20家,想了很久。感觉只有跑背包。。。。
解法把网格看成一张图,与处理出从餐厅到所有点的最短路。那么,就是把所有餐厅分成2组,暴力枚举所有分法,最后送最远的即可。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <cstdlib>
#include <string>
#include <vector>
#include <iostream>
#define maxn 64
using namespace std;
int n,m,dx[]={0,0,1,-1},dy[]={1,-1,0,0};
bool inq[maxn][maxn];
int d[maxn][maxn];
char s[maxn][maxn];
const int INF=1e9;
void spfa(int sx,int sy)
{
for(int i=0;i<n;i++) for(int j=0;j<m;j++) d[i][j]=INF;
queue<pair<int,int> >q;
q.push(make_pair(sx,sy));
d[sx][sy]=0;
while(!q.empty())
{
pair<int,int> now=q.front();
q.pop();
int x=now.first,y=now.second;
inq[x][y]=0;
for(int i=0;i<4;i++)
{
int nx=x+dx[i];
int ny=y+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m)
{
if(s[x][y]=='$'||s[nx][ny]=='$'||s[x][y]=='X'||s[nx][ny]=='X')
{
if(d[nx][ny]>d[x][y]+2)
{
d[nx][ny]=d[x][y]+2;
if(!inq[nx][ny])
q.push(make_pair(nx,ny));
}
}
else if(s[x][y]==s[nx][ny])
{
if(d[nx][ny]>d[x][y]+1)
{
d[nx][ny]=d[x][y]+1;
if(!inq[nx][ny])
q.push(make_pair(nx,ny));
}
}
else if(abs(s[x][y]-s[nx][ny])==1)
{
if(d[nx][ny]>d[x][y]+3)
{
d[nx][ny]=d[x][y]+3;
if(!inq[nx][ny])
q.push(make_pair(nx,ny));
}
}
else
continue;
}
}
}
}
class PizzaDelivery
{
public:int deliverAll(vector <string> ter)
{
n=ter.size();
m=ter[0].length();
int sx=0,sy=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
s[i][j]=ter[i][j];
if(s[i][j]=='X')
{
sx=i;sy=j;
}
}
spfa(sx,sy);
vector<int>des;
for(int i=0;i<n;i++) for(int j=0;j<m;j++)
{
if(s[i][j]=='$')
{
if(d[i][j]==INF)
return -1;
else
des.push_back(d[i][j]);
}
}
sort(des.begin(),des.end());
int m=des.size(),L=0,R=0,ans1,ans2;
int ans=INF;
for(int st=0;st<(1<<m);st++)
{
L=0,R=0,ans1=0,ans2=0;
for(int i=0;i<m;i++)
{
if(st&(1<<i))
{
ans1+=des[i]*2;
L=des[i];
}
else
{
ans2+=des[i]*2;
R=des[i];
}
}
ans1-=L;
ans2-=R;
ans=min(ans,max(ans1,ans2));
}
return ans;
}
};
一开始没看到只有20家,想了很久。感觉只有跑背包。。。。