(POJ 1054)The Troublesome Frog <暴力枚举+剪枝 || DP>
2017-01-17 20:13
429 查看
题目链接:http://poj.org/problem?id=1054
题意:
给定一个行数和列数固定的网格,再给定若干个点,这些点是使用矩形上网格线交叉点的坐标来唯一确定的R行C列的网格,左上角的坐标为(1,1)右下角的坐标为(R,C),问给定的这些点能够组成最长可能路径是多长. 路径的定义的如下的:由若干连续且间隔相等的点组成,方向可任意,起始点和结束点均在网格之外的任意空间.也就是只要满足网格内连续两点之间的间距相等就可以了. 路径上要求至少三个点,而且起点和终点一定要在网格的外部.
分析:
枚举+剪枝
由于题目的数据的大小可以承受住O(n^2)的时间。所以我们可以先将所有点进行排序后,通过枚举每两个点作为一条路径的前两个点,然后求每种情况的值从中求出最大值。其中可以通过题意来进行明显的剪枝。
AC代码:
DP
写出了上面枚举的代码后,我们可以从中得到启发,也可以用DP来解决。(DP只不过是高级的暴力而已)
动态规划解法中,dp[i][j]表示从j到i这条路径中最多经过多少个点. 那么有动态规划方程:
dp[i][j] = max(dp[j][k]) + 1, 其中k满足dist(i, j) = dist(j, k) 且 dir(i, j) = dir(j, k).
求出这些状态后,我们并不一定会取这些值,因为还要满足一个左端点和右端点都在外部.
AC代码:
题意:
给定一个行数和列数固定的网格,再给定若干个点,这些点是使用矩形上网格线交叉点的坐标来唯一确定的R行C列的网格,左上角的坐标为(1,1)右下角的坐标为(R,C),问给定的这些点能够组成最长可能路径是多长. 路径的定义的如下的:由若干连续且间隔相等的点组成,方向可任意,起始点和结束点均在网格之外的任意空间.也就是只要满足网格内连续两点之间的间距相等就可以了. 路径上要求至少三个点,而且起点和终点一定要在网格的外部.
分析:
枚举+剪枝
由于题目的数据的大小可以承受住O(n^2)的时间。所以我们可以先将所有点进行排序后,通过枚举每两个点作为一条路径的前两个点,然后求每种情况的值从中求出最大值。其中可以通过题意来进行明显的剪枝。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <cmath> using namespace std; const int maxn = 5010; short int g[maxn][maxn]; int R,C,N; struct Node { int x,y; }node[maxn]; int cmp(Node a,Node b) { if(a.x != b.x) return a.x < b.x; else return a.y < b.y; } bool judge(int x,int y) { return x>0 && x<=R && y>0 && y<=C; } int deal() { int ans = 2,px,py,cx,cy,dx,dy,len; for(int i=1;i<N;i++) { for(int j=i+1;j<=N;j++) { len = 2; dx = node[j].x - node[i].x;//x之间的距离 dy = node[j].y - node[i].y;//y之间的距离 if(node[j].x + (ans - 2)*dx > R) break;//x方向上判断是否能达到当前ans的值,假设后面点全部存在 if(node[j].y + (ans - 2)*dy <=0 || node[j].y + (ans - 2)*dy > C) continue;//y方向上判断是否能达到当前ans的值,假设后面点全部存在 px = node[i].x - dx; py = node[i].y - dy; if(judge(px,py)) continue;//起点是否在外面 cx = node[j].x; cy = node[j].y; while(judge(cx + dx,cy + dy) && g[cx+dx][cy+dy]) { len++; cx += dx; cy += dy; } if(!judge(cx+dx,cy+dy))//终点是否在外面 { ans = max(ans,len); } } } if(ans >= 3) return ans; else return 0; } int main() { while(scanf("%d%d",&R,&C)!=EOF) { memset(g,0,sizeof(g)); scanf("%d",&N); for(int i=1;i<=N;i++) { scanf("%d%d",&node[i].x,&node[i].y); g[node[i].x][node[i].y] = 1; } sort(node+1,node+N+1,cmp); printf("%d\n",deal()); } return 0; }
DP
写出了上面枚举的代码后,我们可以从中得到启发,也可以用DP来解决。(DP只不过是高级的暴力而已)
动态规划解法中,dp[i][j]表示从j到i这条路径中最多经过多少个点. 那么有动态规划方程:
dp[i][j] = max(dp[j][k]) + 1, 其中k满足dist(i, j) = dist(j, k) 且 dir(i, j) = dir(j, k).
求出这些状态后,我们并不一定会取这些值,因为还要满足一个左端点和右端点都在外部.
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <cmath> using namespace std; const int maxn = 5010; short int g[maxn][maxn];//用来判断点是否被经过,并且去除点的编号 short int dp[maxn][maxn]; int R,C,n; struct Node { int x,y; }node[maxn]; int cmp(Node a,Node b) { if(a.x != b.x) return a.x < b.x; else return a.y < b.y; } bool judge(int x,int y) { return x>0 && x<=R && y>0 && y<=C; } int DP() { int px,py,nx,ny,no; short int ans = -1; for(int i=1;i<=n;i++) { for(int j=1;j<i;j++) { nx = 2*node[j].x - node[i].x;//i->j方向的下一个点:2*(node[j].x-node[i].x)+node[i].x ny = 2*node[j].y - node[i].y; if(judge(nx,ny)) { no = g[nx][ny]; if(no != -1 && dp[j][no] != -1) dp[i][j] = dp[j][no] + 1; else dp[i][j] = -1;//端点在网格内 } else dp[i][j] = 2; px = 2*node[i].x - node[j].x;//起点 py = 2*node[i].y - node[j].y; if(!judge(px,py)) ans = max(ans,dp[i][j]); } } if(ans >= 3) return ans; else return 0; } int main() { while(scanf("%d%d",&R,&C)!=EOF) { memset(g,0xff,sizeof(g)); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&node[i].x,&node[i].y); sort(node+1,node+n+1,cmp); for(int i=1;i<=n;i++) g[node[i].x][node[i].y] = i; printf("%d\n",DP()); } return 0; }
相关文章推荐
- 三大家族(offset、scroll、client)
- 【matlab】syms x y 用法
- BZOJ 1005 明明的烦恼 Prufer序列+组合数学+ 暴力分解质因子
- ecshop 二次开发
- 影响数据库性能的因素
- 各种版本QT下载地址与VS2013+QT5.3.1环境搭建过程
- CRFsuite 学习: CoNLL 2000 shared task
- SQL 时间格式
- 大数加减法
- 排序算法之希尔排序(C/C++)
- 数据库索引使用的好处与坏处
- Spark2.0.2+Zeppelin0.6.2 环境搭建 初探
- python 4-1-1 Linux shell常见的通配符 * ? [a-z] {"a","x"} [!a-z] \
- Mysql数据类型
- 库函数和系统调用的区别
- zoj1382
- Python3基础 str split 用指定的字符将字符串分割
- 探索Android中的Configuration
- Ejabberd源码解读-ejabberd_router模块
- zoj1383