1 条题解
-
0
自动搬运
来自洛谷,原作者为

iwprc
**搬运于
2025-08-24 21:43:17,当前版本为作者最后更新于2017-10-19 21:57:48,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
作为此题目前的最优解,我有必要发一个新的题解:
首先,本题的情景是平面直角坐标系,
分析一下可知要用dp,
设f[i][j][k]为前i秒向北移动j步,向东移动k步最多能挽救的奶牛数
则f[i][j][k]=max(f[i-1][j+1][k],f[i-1][j][k+1],f[i-1][j-1][k],f[i-1][j][k-1])+g[j][k]
而g[j][k]表示全体奶牛向北移动j步,向东移动k步时能挽救的奶牛数
给出代码:
#include<cstdio> const int N=1000,T=31; const int dx[]={1,0,0,-1},dy[]={0,1,-1,0},d[]={69,78,83,87}; //方向增量按字母字典序的顺序给出:E,N,S,W int n,m,k,i,j,s,t,x[N],y[N],p[N],q[N],g[T*2][T*2],f[T][T*2][T*2],u,v; //因为下标不能为负,所以向南向西的负数要加上T使之为正 int max(int x,int y){return x>y?x:y;} int abs(int x){return x>0?x:-x;} int main(){ scanf("%d%d%d",&n,&m,&k); for(i=0;i<n;i++) scanf("%d%d",x+i,y+i); for(i=0;i<m;i++) scanf("%d%d",p+i,q+i); for(i=0;i<n;i++) for(j=0;j<m;j++) if(abs(p[j]-x[i])+abs(q[j]-y[i])<=k) g[p[j]-x[i]+T][q[j]-y[i]+T]++; //g数组由初始化得到,只要奶牛和草垛的曼哈顿距离<=k,便是可达的 for(t=k;t>=0;t--)//阶段从大到小枚举是为了输出使字典序最小方便 for(u=T-t;u<=T+t;u++) for(v=T-t;v<=T+t;v++){ for(i=0;i<4;i++) f[t][u][v]=max(f[t+1][u+dx[i]][v+dy[i]],f[t][u][v]); f[t][u][v]+=g[u][v]; } printf("%d\n",f[0][T][T]); u=T;v=T; for(i=0;i<k;i++){ for(j=0;j<4;j++) if(f[i][u][v]==f[i+1][u+dx[j]][v+dy[j]]+g[u][v]) break; //只要发现本状态是由第j个决策得来的就退出循环,输出 u+=dx[j];v+=dy[j]; printf("%c",d[j]); } return 0; } //时间复杂度:O(n*m+k^3) //空间复杂度:O(n+m+k^3)
- 1
信息
- ID
- 1970
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者