拜访(动态规划)
来源:互联网 发布:c语言枚举法例题 编辑:程序博客网 时间:2024/04/28 10:15
题目描述
现在有一个城市销售经理,需要从公司出发,去拜访市内的商家,已知他的位置以及商家的位置,但是由于城市道路交通的原因,他只能在左右中选择一个方向,在上下中选择一个方向,现在问他有多少种方案到达商家地址。给定一个地图map及它的长宽n和m,其中1代表经理位置,2代表商家位置,-1代表不能经过的地区,0代表可以经过的地区,请返回方案数,保证一定存在合法路径。保证矩阵的长宽都小于等于10。
测试样例:
[[0,1,0],[2,0,0]],2,3
返回:2
解题思路:
因为题目限制了在某个位置经理只能往两个方向走,所以就经理全程只有四种可以走的走法分别为左上、左下、右上、右下。所以一开始要判断经理和商家的方向,找到其行走的方向,若商家在经理的左下方则经理全程只能向左或者向下行走。
例如经理在黄色位置,商家在蓝色位置,橘色的为不能走的位置,空白的为可以走的路径,则经理只能往左下走。
动态规划思想:
每一个位置可以走的位置可以由其左上、左下、右上、右下相加得到,当选定一个方向之后只能由该方向的相加得到,如上面的例子只能由其上方和右边两个位置可达路径相加。
所以一开始只能由经理所在的位置往商家所在的位置斜着移动,动态的获得路径和。
经理只能往下或者往走,所以其到商家的位置等于商家所在的位置的上方位置的可达路径数+商家所在的位置的右方的可到达路径数的和,即为2。
代码
public int countPath(int[][] map, int n, int m) {
// write code here
// int solveSum = 0;
int r = 0, c = 0;
int comRow = -1, comCol = -1, businessRow = -1, businessCol = -1;
// 寻找公司和商人所在的位置
for (r = 0; r < n; r++) {
for (c = 0; c < m; c++) {
if (map[r][c] == 1) {
comRow = r + 1;// 公司所在的行,+1是方便后面进行计算
comCol = c + 1;// 公司所在的列,+1是方便后面进行计算
}
if (map[r][c] == 2) {
businessRow = r + 1;// 商人所在的行,+1是方便后面进行计算
businessCol = c + 1;// 商人所在的列,+1是方便后面进行计算
}
if (comRow != -1 && businessRow != -1)
break;
}
}
int rd = businessRow - comRow, cd = businessCol - comCol;
int solveMap[][] = new int[n + 2][m + 2];// 解决方案矩阵
for (r = 0; r < n; r++) {
for (c = 0; c < m; c++) {
if (map[r][c] != -1)
solveMap[r + 1][c + 1] = 0;
else
solveMap[r + 1][c + 1] = -1;
}
}
for (r = 0; r < n + 2; r++) {// 外围的解都等于-1不可达
solveMap[r][0] = -1;
solveMap[r][m + 1] = -1;
}
for (c = 0; c < m + 2; c++) {
solveMap[0][c] = -1;
solveMap[n + 1][c] = -1;
}
int tmp = 0; tmp = comRow; int rdirection = businessRow > comRow ? 1 : -1; for (r = 0; r < Math.abs(rd); r++) {// 处理和该公司所在列的可达方案数顶多为1 tmp = tmp + rdirection;// 判断是加还是减 if (solveMap[tmp][comCol] == -1 || solveMap[tmp - rdirection][comCol] == -1) solveMap[tmp][comCol] = -1;// 判断当前位置是否为-1,或者前一行是否为-1 else solveMap[tmp][comCol] = 1;// 当前位置都为1 } tmp = comCol; int cdirection = businessCol > comCol ? 1 : -1; for (c = 0; c < Math.abs(cd); c++) { tmp = tmp + cdirection;// 判断是加还是减 if (solveMap[comRow][tmp] == -1 || solveMap[comRow][tmp - cdirection] == -1) solveMap[comRow][tmp] = -1; else solveMap[comRow][tmp] = 1;// 当前位置的为1 } // for(r=0; r < n+2; r++){ // for(c = 0; c < m+2; c++){ // System.out.print(solveMap[r][c]+" "); // } // System.out.println(); // } // 动态规划求解 int tmpRow = comRow; for (r = 0; r < Math.abs(rd); r++) { int tmpCol = comCol; tmpRow += rdirection; for (c = 0; c < Math.abs(cd); c++) { tmpCol += cdirection; solveMap[tmpRow][tmpCol] = towSum(solveMap[tmpRow][tmpCol - cdirection], solveMap[tmpRow - rdirection][tmpCol]);// 等于前一行或者同行两个的和 } } // for(r=0; r < n+2; r++){ // for(c = 0; c < m+2; c++){ // System.out.print(solveMap[r][c]+" "); // } // System.out.println(); // } return solveMap[businessRow][businessCol];}/** * 返回两个数的正数和,若两则都为负数则返回0 * @param a * @param b * @return */int towSum(int a, int b) { int sum = a; if (a < 0) sum = 0; if (b > 0) sum = sum + b; return sum;}
这个题目理解了半天,描述的不是很清楚,经理到商家只能向两个方向移动,其他方向不能移动。
- 拜访(动态规划)
- (牛客)拜访(动态规划)
- 拜访---动态规划
- 拜访-动态规划
- 动态规划-美团笔试题-拜访
- 拜访(动态规划)----美团2016研发工程师在线编程题
- |BZOJ 2060|动态规划|Visiting Cows 拜访奶牛
- 拜访
- 拜访
- 拜访
- 拜访
- 拜访
- 拜访
- 【动态规划(一)】动态规划基础
- 拜访 动态规划DP, 从起点开始循环,注意同行同列的边界条件,同时注意判断-1障碍物的情况
- 动态规划(1)
- 动态规划(2)
- 动态规划(3)
- 实习总结系列4
- IFE task13-16知识点
- lavarel之容器Application构造函数分析
- 类、对象和包
- Hibernate的Annotation注解
- 拜访(动态规划)
- Linux指令汇集
- ViewDragHelper_v4的滑动视图帮助类_解释和代码
- JavaBean
- Hibernate的抓取策略
- linux的sendfile系统调用
- listview 嵌套gridview notifyDataSetChanged无效
- 常用的两款代码文档生成器
- Findbugs 缺陷详解与英文代号的对照表