BZOJ 1605 [Usaco2008 Open]Crisis on the Farm 牧场危机 DP
2017-06-30 16:19
465 查看
题意:链接
方法: DP
解析:
第一眼搜索题,复杂度不同意dfs,并且牛的数量太多不能bfs,迭代更不可能,A*不会估价。可能记忆化?
等等记忆化我还搜个毛线…
直接改成DP就好了。
状态非常好想非常easy,可是这个路径简直….丧心病狂!
f[i][j][k]表示横向走了(i-31),纵向走了(j-31)用了k次的最大值。
所以我们要预处理map[i][j]表示横向走到(i-31),纵向走到(j-31),这么一下对答案的贡献。
然后我就要吐槽了。这个题假设你不处理一些奇怪的点,比方走到坐标为x,0或是0,y的地方是合法的。合法的!
所以题里那个>=1不是限制这个的?简直丧病!
然后就是欢快地搜路径辣。
到着搜全部路径。字典序的方向优先选用。
最后正着跑一边就好了。
说起来挺简单。
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 35 #define INF 0x3f3f3f3f using namespace std; int n,m,k; struct node { int x,y; }pt[1010]; int f[N<<1][N<<1] ; char pre[N<<1][N<<1] ; int map[N<<1][N<<1]; int map_ori[1010][1010]; int xx[5]={0,-1,0,0,1}; int yy[5]={0,0,-1,1,0}; bool canbetheend ; char printout ; char comp ; char pick ; void init_map() { for(int i=0;i<=62;i++) { for(int j=0;j<=62;j++) { int basex,basey; basex=i-31,basey=j-31; int flag=0; for(int l=1;l<=n;l++) { if(i==29&&j==30) { flag++; flag--; } int x=pt[l].x,y=pt[l].y; if(x+basex<=0||y+basey<=0||x+basex>1000||y+basey>1000){flag=1;continue;} map[i][j]+=map_ori[x+basex][y+basey]; } } } } int main() { pick[1]='W',pick[2]='S',pick[3]='N',pick[4]='E'; scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++)scanf("%d%d",&pt[i].x,&pt[i].y); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); map_ori[x][y]++; } init_map(); int ans=0; for(int i=0;i<=k;i++) { for(int j=0;j<=62;j++) { for(int l=0;l<=62;l++) { f[j][l][i]=-INF,pre[j][l][i]='Z'; } } } f[31][31][0]=0; for(int i=1;i<=k;i++) { for(int j=1;j<=61;j++) { for(int l=1;l<=61;l++) { f[j][l][i]=max(max(f[j-1][l][i-1],f[j][l-1][i-1]),max(f[j][l+1][i-1],f[j+1][l][i-1]))+map[j][l]; if(i==k) { if(f[j][l][i]>ans) { ans=f[j][l][i]; } } } } } for(int i=1;i<=61;i++) { for(int j=1;j<=61;j++) { if(f[i][j][k]==ans) { pre[i][j][k]='A'; } } } for(int l=k-1;l>=0;l--) { for(int i=1;i<=61;i++) { for(int j=1;j<=61;j++) { for(int o=1;o<=4;o++) { if(f[i][j][l]+map[i+xx[o]][j+yy[o]]==f[i+xx[o]][j+yy[o]][l+1]&&pre[i+xx[o]][j+yy[o]][l+1]<'Z') { pre[i][j][l]=pick[o]; } } } } } printf("%d\n",ans); int li=31,lj=31; for(int i=0;i<k;i++) { printf("%c",pre[li][lj][i]); switch(pre[li][lj][i]) { case 'E':li++;break; case 'N':lj++;break; case 'S':lj--;break; case 'W':li--;break; } } cout<<endl; }
相关文章推荐
- 麻烦的DP-BZOJ-1605-[Usaco2008 Open]Crisis on the Farm 牧场危机
- bzoj 1605: [Usaco2008 Open]Crisis on the Farm 牧场危机(DP)
- BZOJ 1605 [Usaco2008 Open]Crisis on the Farm 牧场危机 DP
- BZOJ1605 [Usaco2008 Open]Crisis on the Farm 牧场危机
- BZOJ1605: [Usaco2008 Open]Crisis on the Farm 牧场危机
- [Usaco2008 Open]Crisis on the Farm 牧场危机
- 【BZOJ1589】[Usaco2008 Dec]Trick or Treat on the Farm 采集糖果【SCC】【基环外向树】【DP】【记忆化搜索】
- bzoj1589 [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果(tarjan缩点+记忆化搜索)
- BZOJ 1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场
- BZOJ 1619 USACO 2008 Nov Guarding the Farm 保卫牧场
- Bzoj 1619 [Usaco2008 Nov]Guarding the Farm 保卫牧场
- bzoj1619[Usaco2008 Nov]Guarding the Farm 保卫牧场
- bzoj1619【Usaco2008 Nov】Guarding the Farm 保卫牧场
- BZOJ 1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果 记忆化搜索
- BZOJ 1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果
- [Usaco2008 Dec][BZOJ1589] Trick or Treat on the Farm 采集糖果
- bzoj 1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果
- |BZOJ 1619|搜索|[Usaco2008 Nov]Guarding the Farm 保卫牧场
- 【USACO 2008 Open Gold】 2.Crisis on the Farm 动规、
- [BZOJ1589] [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果(tarjan缩点 + 记忆化搜索)