传送门

DP

设 f [ i ] [ j ] [ k ] 表示已经走了 i 步,向上走了 j 步,向右走了 k 步时能拯救的最多奶牛数(j,k可以为负,表示反向)

设 g [ i ] [ j ] 表示牛向上走 i 步,向右走 j 步后有多少奶牛恰好在草堆上(同样 i , j 可负)

那么 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 ]

因为数组下标不能为负,所以要把坐标集体加上一个 K

为了方便按字典序输出,我们要倒过来推,并且要按字典序的方向来枚举

即从 f [ k ] 推到 f [ 0 ] 枚举方向为 'E' 'N' 'S' 'W'

好像不太好讲,具体还是看代码吧,代码不难的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=,K=;
int n,m,k;
int xx[]={,,,-},yy[]={,,-,};
char mp[]={'E','N','S','W'};
int f[K<<][N][N],g[K<<][K<<];
int cow[N][],hay[N][];
int main()
{
n=read(); m=read(); k=read();
for(int i=;i<=n;i++) cow[i][]=read(),cow[i][]=read();
for(int i=;i<=m;i++) hay[i][]=read(),hay[i][]=read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(abs(hay[j][]-cow[i][])+abs(hay[j][]-cow[i][])<=k)//如果可以到达才计算贡献
g[hay[j][]-cow[i][]+K][hay[j][]-cow[i][]+K]++;//预处理g
for(int i=k;i>=;i--)
for(int x=K-i;x<=K+i;x++)
for(int y=K-i;y<=K+i;y++)//注意大小写K的区别
{
for(int o=;o<;o++) f[i][x][y]=max(f[i][x][y],f[i+][x+xx[o]][y+yy[o]]);
f[i][x][y]+=g[x][y];
}
printf("%d\n",f[][K][K]);
int posx=K,posy=K;//存当前位置
for(int i=;i<k;i++)
{
int o;
for(o=;o<;o++) if(f[i][posx][posy]==f[i+][posx+xx[o]][posy+yy[o]]+g[posx][posy]) break;//如果是从o推过来的就断开
posx+=xx[o]; posy+=yy[o];
printf("%c",mp[o]);
}
return ;
}

P2905 [USACO08OPEN]农场危机Crisis on the Farm的更多相关文章

  1. bzoj1605 / P2905 [USACO08OPEN]农场危机Crisis on the Farm

    P2905 [USACO08OPEN]农场危机Crisis on the Farm 发现总步数$k<=30$,考虑用$k$瞎搞 设$f[u][i][j]$表示已经吹$u$次哨,全体奶牛向右走$i ...

  2. 洛谷P2905 [USACO08OPEN]农场危机Crisis on the Farm

    P2905 [USACO08OPEN]农场危机Crisis on the Farm 题目描述 约翰和他的奶牛组建了一只乐队“后街奶牛”,现在他们正在牧场里排练.奶牛们分成一堆 一堆,共1000)堆.每 ...

  3. 洛谷 P2905 [USACO08OPEN]农场危机Crisis on the Farm

    题目描述 约翰和他的奶牛组建了一只乐队“后街奶牛”,现在他们正在牧场里排练.奶牛们分成一堆 一堆,共1000)堆.每一堆里,30只奶牛一只踩在另一只的背上,叠成一座牛塔.牧场 里还有M(1 < ...

  4. P2905 [USACO08OPEN]农场危机Crisis on the Farm(简单dp+麻烦“回溯”)

    惯例,化简题意(看长短决定难度) 一块草坪上有两种点(姑且称为a和b),各有坐标,现在能同时使所有a点向东西南北任意一个方向移动一个单位,若a点与b点重合,则答案增加重合数,求答案的最大值并且求出这个 ...

  5. bzoj1621 / P2907 [USACO08OPEN]农场周围的道路Roads Around The Farm

    P2907 [USACO08OPEN]农场周围的道路Roads Around The Farm 基础dfs,按题意递归即可. #include<iostream> #include< ...

  6. [USACO08OPEN]农场周围的道路Roads Around The Farm BZOJ 1621 DFS

    Farmer John's cows have taken an interest in exploring the territory around the farm. Initially, all ...

  7. BZOJ1605 [Usaco2008 Open]Crisis on the Farm 牧场危机

    标题好长&&我是权限狗,汪汪! 题没看懂的我以为这是一道极难滴题目...然后,然后我就看懂题了. 数据少给了一个条件K <= 30...(没这条件还做个鬼...) f[k, i, ...

  8. BZOJ 1605 [Usaco2008 Open]Crisis on the Farm 牧场危机:dp【找转移路径】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1605 题意: 平面直角坐标系中,有n个点,m个标记(坐标范围1~1000). 你可以发出口 ...

  9. BZOJ 1605 [Usaco2008 Open]Crisis on the Farm 牧场危机 DP

    题意:链接 方法: DP 解析: 第一眼搜索题,复杂度不同意dfs,并且牛的数量太多不能bfs,迭代更不可能,A*不会估价.可能记忆化? 等等记忆化我还搜个毛线- 直接改成DP就好了. 状态非常好想非 ...

随机推荐

  1. js实现导航栏的吸顶操作

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  2. Android中无标题样式和全屏样式学习

    在进行UI设计时,我们经常需要将屏幕设置成无标题栏或者全屏.要实现起来也非常简单,主要有两种方法:配置xml文件和编写代码设置. 1.在xml文件中进行配置 在项目的清单文件AndroidManife ...

  3. [poj2398]Toy Storage

    接替关键:和上题类似,输出不同,注意输入这道题需要排序. #include<cstdio> #include<cstring> #include<algorithm> ...

  4. C++指针作为函数的参数进行传递时注意的问题

    应注意问题: 当指针作为函数的参数进行传递的时候,本质上还是进行的"值传递",也就是复制了一个新的指向该地址的指针变量. 只有在被调函数中,对指针进行引用操作,才可以达到不需要返回 ...

  5. 安装了多个php版本,如何编译扩展

    cd /data/php-5.5.35/ext/mysqli  找到安装包目录下面的ext目录 ./configure --with-php-config=/usr/local/php5/bin/ph ...

  6. Windows中lib和DLL区别和使用

    本文转载自:http://www.cppblog.com/amazon/archive/2009/09/04/95318.html 共有两种库:一种是LIB包含了函数所在的DLL文件和文件中函数位置的 ...

  7. 说说excel

    今天遇到一个实际问题. 我有一组数据: 0.0.0.1 activate.adobe.com 0.0.0.1 practivate.adobe.com 0.0.0.1 ereg.adobe.com 0 ...

  8. Luogu 1484 种树

    Luogu 1792 算是双倍经验. 我们考虑对于一个点,我们要么选它,要么选它周围的两个点. 所以我们考虑用一个堆来维护,每次从堆顶取出最大值之后我们把它的权值记为:它左边的权值加上它右边的权值减去 ...

  9. Entity Framework Tutorial Basics(17):DBSet Class

    DBSet Class DBSet class represents an entity set that is used for create, read, update, and delete o ...

  10. left join和right join、inner join 区别

    left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录  right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录 inner join(等值连接) ...