题目链接: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. apue学习笔记(第十四章 高级I/O)

    本章涵盖了从多概念和函数:非阻塞I/O.记录锁.I/O多路转换.异步I/O.readv和writev函数以及存储映射I/O 非阻塞I/O 非阻塞I/O使我们可以发出open.read和write这样的 ...

  2. jquery方法

    $.inArray(被判断的量,ArrayName);  如果存在返回索引值,如果不存在返回-1 $.unique() 数组去重   根据去重前后的长度,判断是否有重复 $.each(被遍历的数组,f ...

  3. spring-web中的WebDataBinder理解

    Spring可以自动封装Bean,也就是说前台通过SpringMVC传递过来的属性值会自动对应到对象中的属性并封装成javaBean,但是只能是基本数据类型(int,String等).如果传递过来的是 ...

  4. cocos2dx中使用iconv转码(win32,iOS,Android)

    首先贴下环境:Win7 64, NDK r8e, libiconv-1.14, cygwin 一 Win32环境配置 Cocos2D-X自带有win32上的iconv库.仅仅须要配置一下就可以使用. ...

  5. 我的ngnix 配置内容

    #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #erro ...

  6. java 中的CountDownLatch

    直接使用thread可以使用thread和wait notify 实现顺序执行 线程池中可以使用CountDownLatch 进行顺序执行 package com.test; import java. ...

  7. 【Linux】OpenWRT的无线设置注意事项——从2.4G到5G,hwmode不简单

    硬件说明: 操作系统:OpenWRT 网卡:AR9220R52Hn 网卡驱动:ath9k OpenWRT在刷机完成之后,并不会自动开启无线功能,需要手动修改配置文件,然后重启网络服务.管理无线功能的配 ...

  8. 【nginx】关于Nginx的一些优化(突破十万并发)

    nginx指令中的优化(配置文件) worker_processes 8; nginx进程数,建议按照cpu数目来指定,一般为它的倍数. worker_cpu_affinity 00000001 00 ...

  9. React系列之--props属性

    版权声明:本文为博主原创文章,未经博主允许不得转载. PS:转载请注明出处作者:TigerChain地址:http://www.jianshu.com/p/fa81cebac3ef本文出自TigerC ...

  10. kaptcha的和springboot一起使用的简单例子

    https://blog.csdn.net/xiaoyu19910321/article/details/79296030