题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1605

题意:

  平面直角坐标系中,有n个点,m个标记(坐标范围1~1000)。

  你可以发出口令,让所有点整体向东、南、西、北四个方向中的任意一个方向移动,口令分别记作'E','S','W','N'。

  每当一个点碰到一个标记,则答案+1。(保证初始时没有点在标记上)

  你最多可以发出t次口令。

  问你答案最大是多少,并输出字典序最小的口令序列。

题解:

  表示状态:

    dp[i][j][k] = max survivors

    i:水平方向共移动了i个单位(左负右正)

    j:竖直方向共移动了j个单位(下负上正)

    k:发了k次口令

    (因为数组下标有负数,所以最后再给i,j统一加上30就好啦,现在先不管它)

  找出答案:

    max dp[i][j][k]

  如何转移:

    先预处理cnt数组:cnt[x][y]表示移动了(x,y)时,碰到标记的点的个数。

    dp[x][y][k] = cnt[x][y] + max dp[lx][ly][k-1]

    lx=i-dx[p], ly=j-dy[p] (p = 0 to 3)

  边界条件:

    dp[0][0][0] = 0

    others = -INF(不存在)

  输出序列:

    说明:

      (1)feas[x][y][k],用来判断最终答案是否由状态(x,y,k)转移而来。

      (2)way[x][y][k],表示在状态(x,y,k)时发出的口令。

    总共三步:

      (1)先将feas全部设为false,再将最终答案的feas改为true。

      (2)枚举k(从大到小),i,j,判断当前(i,j,k)是否能转移到最终答案。如果能,更新当前way和feas。

      (3)枚举k(从小到大),当前位置为(x,y),输出way[x][y][k],并更新(x,y)。

AC Code:

 // state expression:
// dp[i][j][k] = max survivors
// i,j: moving dist
// k: whistling times
//
// find the answer:
// max dp[i][j][t]
//
// transferring:
// dp[x][y][k] = cnt[x][y] + max dp[lx][ly][k-1]
//
// boundary:
// dp[0][0][0] = 0
// others = -INF
//
// find the way:
// if dp[nx][ny][k+1] == cnt[nx][ny] + dp[x][y][k] and feas[nx][ny][k+1]
// way[x][y][k] = c[p]
// feas[x][y][k] = true
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_N 1005
#define MAX_T 65
#define MAX_K 35
#define INF 10000000 using namespace std; const int dx[]={,,,-};
const int dy[]={,,-,};
const char c[]={'E','N','S','W'}; int n,m,t;
int ans=;
int cx[MAX_N];
int cy[MAX_N];
int gx[MAX_N];
int gy[MAX_N];
int cnt[MAX_T][MAX_T];
int dp[MAX_T][MAX_T][MAX_K];
bool feas[MAX_T][MAX_T][MAX_K];
char way[MAX_T][MAX_T][MAX_K]; void read()
{
cin>>n>>m>>t;
for(int i=;i<n;i++)
{
cin>>cx[i]>>cy[i];
}
for(int i=;i<m;i++)
{
cin>>gx[i]>>gy[i];
}
} void cal_cnt()
{
memset(cnt,,sizeof(cnt));
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
int x=gx[j]-cx[i];
int y=gy[j]-cy[i];
if(abs(x)+abs(y)<=t) cnt[x+][y+]++;
}
}
} void cal_dp()
{
for(int k=;k<=t;k++)
{
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
dp[i][j][k]=-INF;
}
}
}
dp[][][]=;
for(int k=;k<=t;k++)
{
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
if(i+j->t) continue;
for(int p=;p<;p++)
{
int lx=i-dx[p];
int ly=j-dy[p];
dp[i][j][k]=max(dp[i][j][k],cnt[i][j]+dp[lx][ly][k-]);
}
ans=max(ans,dp[i][j][k]);
}
}
}
} void cal_way()
{
memset(feas,false,sizeof(feas));
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
if(dp[i][j][t]==ans) feas[i][j][t]=true;
}
}
for(int k=t-;k>=;k--)
{
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
for(int p=;p<;p++)
{
int nx=i+dx[p];
int ny=j+dy[p];
if(dp[nx][ny][k+]==cnt[nx][ny]+dp[i][j][k] && feas[nx][ny][k+])
{
way[i][j][k]=c[p];
feas[i][j][k]=true;
break;
}
}
}
}
}
} void solve()
{
cal_cnt();
cal_dp();
cal_way();
} void print()
{
cout<<ans<<endl;
int x=;
int y=;
for(int k=;k<t;k++)
{
cout<<way[x][y][k];
for(int p=;p<;p++)
{
if(way[x][y][k]==c[p])
{
x+=dx[p];
y+=dy[p];
break;
}
}
}
} int main()
{
read();
solve();
print();
}

BZOJ 1605 [Usaco2008 Open]Crisis on the Farm 牧场危机:dp【找转移路径】的更多相关文章

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

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

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

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

  3. BZOJ 1621: [Usaco2008 Open]Roads Around The Farm分岔路口

    题目 1621: [Usaco2008 Open]Roads Around The Farm分岔路口 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 56 ...

  4. BZOJ 1621 [Usaco2008 Open]Roads Around The Farm分岔路口:分治 递归

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1621 题意: 约翰的N(1≤N≤1,000,000,000)只奶牛要出发去探索牧场四周的土 ...

  5. bzoj 1621: [Usaco2008 Open]Roads Around The Farm分岔路口【dfs】

    模拟就行--讲道理这个时间复杂度为啥是对的??? #include<iostream> #include<cstdio> using namespace std; int k, ...

  6. bzoj 1231: [Usaco2008 Nov]mixup2 混乱的奶牛 -- 状压DP

    1231: [Usaco2008 Nov]mixup2 混乱的奶牛 Time Limit: 10 Sec  Memory Limit: 162 MB Description 混乱的奶牛 [Don Pi ...

  7. BZOJ 1616 [Usaco2008 Mar]Cow Travelling游荡的奶牛:dp【网格型】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1616 题意: 有一个n*m的网格. '.'表示平坦的草地,'*'表示挡路的树(不能走). ...

  8. bzoj 1609[Usaco2008 Feb]Eating Together麻烦的聚餐【dp】

    设up[i][j]为第i位升序为j的最小修改数,down为降序 #include<iostream> #include<stdio.h> using namespace std ...

  9. bzoj 1616: [Usaco2008 Mar]Cow Travelling游荡的奶牛【dp】

    写了个bfs发现MLE了... 设f[t][i][j]为在t时刻走到(i,j)的方案数,转移和bfs一样 #include<iostream> #include<cstdio> ...

随机推荐

  1. HDU 3461 Code Lock(并查集的应用+高速幂)

    * 65536kb,仅仅能开到1.76*10^7大小的数组. 而题目的N取到了10^7.我開始做的时候没注意,用了按秩合并,uset+rank达到了2*10^7所以MLE,所以貌似不能用按秩合并. 事 ...

  2. 分布式搜索elasticsearch 环境搭建

    1.elasticsearch安装 elasticsearch的安装超级easy,解压即用(要事先安装好java环境). 到官网 http://www.elasticsearch.org下载最新版的 ...

  3. hibernate 配置文件无自动提示

    在编辑 *.hbm.xml 文件时,myeclipse 带有自动提示功能,但 eclipse 是没有自动提示功能的.需要自己手工加上:           1.打开项目中任意一个 *.hbm.xml ...

  4. servletResponse 文件下载

    package response; import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOEx ...

  5. 华为p20:拍美景,听讲解,旅行更智能

    华为P20轰轰烈烈地上市了,本来对手机并不感冒的我,看到身边的好友换了P20,不禁感慨:这个月的活又要白干了,全部都要上交给华为,因为这款手机完全戳中了旅游爱好者的痛点. 痛点一:丢弃笨重的单反,手机 ...

  6. 记录下关于ejabberd及XMPP的官网链接

    ejabberd中文翻译 ——http://wiki.jabbercn.org/Ejabberd2:安装和操作指南 XMPP中文翻译: http://wiki.jabbercn.org/XEP-012 ...

  7. Koa2+MySQL+VUE+ElementIUI搭建简单的后台管理小系统

    如题,前端入坑许久,还是写个小东西出来吧 想要搭建自己的一个后台管理,实现简单的增删改查,看起来很简单 其实是真的简单,没有想的那么难,我也就写了一个月吧, 当然是假的,其实也就每天一两个小时,花了大 ...

  8. 特权级概述(哥子就想知道CPU是如何验证特权级的)GATE+TSS

    [0]README text description from orange's implemention of a os . [1]特权级概述 当当前代码段试图访问一个段或者门时,目标段的DPL将会 ...

  9. 图像检测之sift and surf---sift中的DOG图 surf hessian

    http://www.cnblogs.com/tornadomeet/archive/2012/08/17/2644903.html http://www.cnblogs.com/slysky/arc ...

  10. antd引入普通html使用,将ant Design本地化

    一直想着能本地化antd的,不用npm以及dva那么复杂的配置环境来开发,并且本地化以后对以后链接flask的模板渲染机制也能很好的结合.下面是具体的实现方法: 1.将react的相关链接引入: &l ...