美团的三道原题…好多人都ak了
「美团 CodeM 初赛 Round A」身体训练
随便推推
O(n2)
就过了…
「美团 CodeM 初赛 Round B」景区路线规划
事实证明爆搜没前途啊…考完发现只要加个记忆化就过了…
首先两个人肯定是独立的…搜索的过程中记忆化一下
dp[x][time][opt]
表示每个人到
x
点时间还剩
事实证明我的记忆化水平不高啊…
double dfs(int x,int time,int opt)
{
if(dp[x][time][opt]) return dp[x][time][opt];
int i,down=0;
for(i=head[x];i;i=e[i].next)
if(time>=e[i].t+c[e[i].to]) ++down;
double res=h[opt][x];
for(i=head[x];i;i=e[i].next)
if(time>=e[i].t+c[e[i].to])
res+=dfs(e[i].to,time-e[i].t-c[e[i].to],opt)/down;
return dp[x][time][opt]=res;
}
「美团 CodeM 初赛 Round B」送外卖2
最近在学状压,一眼就觉得是个状压题
3进制,0表示没拿到,1表示拿到了,2表示送到了
dp[x][state]
当前在
x
点状态为
一重循环枚举状态
一重循环枚举当前在的位置
一重枚举订单
xjb转移一下//只用处理0,1的位可以不用进位好开心
然后算一下答案
#include<cstdio>
#include<algorithm>
#include<cstring>
#define INF 1e9
using namespace std;
struct task{int s,t,l,r;}T[11];
int n,m,q,ans,map[21][21],dp[21][59049+5],pow[11];
void init()
{
scanf("%d %d %d",&n,&m,&q);
int i,j,k,x,y,v;
for(i=1,pow[0]=1;i<=q;++i) pow[i]=pow[i-1]*3;
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
map[i][j]=INF;
for(i=1;i<=n;++i) map[i][i]=0;
for(i=1;i<=m;++i)
{
scanf("%d %d %d",&x,&y,&v);
map[x][y]=min(map[x][y],v);
}
for(k=1;k<=n;++k)
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
if(i!=j&&j!=k)
map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
for(i=1;i<=q;++i)
scanf("%d %d %d %d",&T[i].s,&T[i].t,&T[i].l,&T[i].r);
}
int c[10];
int main()
{
init();
int i,j,state,now,id,tmp;
for(i=0;i<pow[q];++i) for(j=1;j<=n;++j) dp[j][i]=INF;
for(now=1;now<=n;++now)
dp[now][0]=map[1][now];
for(state=0;state<pow[q];++state)
for(now=1;now<=n;++now)
for(id=1;id<=q;++id)
{
tmp=state%pow[id]/pow[id-1];
if(tmp==0)
if(dp[now][state]+map[now][T[id].s]>=T[id].l)
dp[T[id].s][state+pow[id-1]]=min(dp[T[id].s][state+pow[id-1]],dp[now][state]+map[now][T[id].s]);
else dp[T[id].s][state+pow[id-1]]=min(T[id].l,dp[T[id].s][state+pow[id-1]]);
if(tmp==1)
if(dp[now][state]+map[now][T[id].t]<=T[id].r)
dp[T[id].t][state+pow[id-1]]=min(dp[T[id].t][state+pow[id-1]],dp[now][state]+map[now][T[id].t]);
}
ans=0;
for(state=0;state<pow[q];++state)
{
for(i=1;i<=n;++i)
if(dp[i][state]!=1e9)
{
tmp=0;
for(j=1;j<=q;++j) if(state%pow[j]/pow[j-1]==2) ++tmp;
ans=max(ans,tmp);
}
}
printf("%d\n",ans);
return 0;
}