POJ 1088 skiing


http://poj.org/problem?id=1088
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
 1  2  3  4 5

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
http://java-mans.iteye.com/blog/1640564
定义 m[i][j] 表示从点 (i,j) 为起点滑行的最大长度。滑行时,选择周围可以滑行的且 m 值最大的方向滑行。如果 (i,j) 的四个相邻元素都存在的话,则可以得到如下递归式:
m[i][j]=Max(m[i][j-1],m[i][j+1],m[i-1][j],m[i+1][j]) +1
通过递归地计算 m[i][j-1],m[i][j+1],m[i-1][j] 和 m[i+1][j] 的值,找中四个中最大的一个,即是下一步滑行的位置,以此递归,直到不能继续滑行时返回。求解过程中,每求解到一个点的最大滑行长度则保存在数组m[i][j]中,因此不会重复求解同一个点的最大滑行长度。
const int x[]={-1,0,1,0},y[]={0,1,0,-1}; //巧妙之处
int r,c;
int node[101][101];
int ppt[101][101];
//深搜
int dfs(int i,int j)
{
int k;
if(ppt[i][j]) //不为0,说明被访问过,直接返回
return ppt[i][j];
for(k=0;k<4;k++)//k值是为了决定x和y的方向(上下左右)
if(i+x[k]>=1 && i+x[k]<=r && j+y[k]>=1 && j+y[k]<=r) //没有越界
if( node[i+x[k]][j+y[k]]<node[i][j] ) //周围某点(上下左右之一,看循环的值了)高度小于当前点
if( ppt[i][j]< dfs(i+x[k],j+y[k])+1 ) //当前点的最大滑雪长度小于等于周围某点
ppt[i][j]=dfs(i+x[k],j+y[k])+1; //更改当前点的最大滑雪长度
return ppt[i][j];
}
http://www.douban.com/note/209925117/
bool ok(int i,int j)
{
  return (i>=1 && i<=r && j>=1 &&j<=c);
}

int dp(int i,int j)
{
    int k;
    if(opt[i][j]>0) return opt[i][j]; //如果已经计算出,直接返回
    for(k=0;k<4;k++) //向四个方向延伸
    {
        if(ok(i+dx[k],j+dy[k])) //如果节点没有超出边界
            if( node[i+dx[k][j+dy[k]<node[i][j] ) //满足滑雪条件
            {
                if( opt[i][j]< dp(i+dx[k],j+dy[k])+1 )
                         opt[i][j]=dp(i+dx[k],j+dy[k])+1;
            }
    }
    return opt[i][j];
}
http://www.cnblogs.com/yrbbest/p/5126855.html
这是POJ经典的记忆化搜索结构题目,给定一个二维矩阵里,找到一条最长的下降坡道(4-connected,从最大值到最小值为递减的一条path)。
我们主要可以维护一个count[][]矩阵,对上下左右分别用dfs来记录下每个位置的最大count。之后也要做一些pruning,比如当count[i][j] > 0的时候,表示这个位置已经被计算过,可以直接返回count[i][j]来省略重复计算。 
public class Solution {
    private int[][] count;
    
    public int findDownHillSki(int[][] board) {        
        count = new int[board.length][board[0].length];        // matrix count for counting        
        int max = 0;
        for (int i = 0; i < board.length; i++) {            // fill count[][] using findMax(i, j, board)
            for (int j = 0; j < board[0].length; j++) {
                findMax(i, j, board);
                max = Math.max(max, count[i][j]);
            }
        }        
        return max;
    }
    
    private int findMax(int i, int j, int[][] board) {
        int max = 0;
        if (count[i][j] > 0) {
            return count[i][j]; 
        }
        
        if (i - 1 >= 0) {
            if (board[i][j] > board[i - 1][j]) {                
                max = Math.max(max, findMax(i - 1, j, board));
            }
        }
        if (j - 1 >= 0) {
            if (board[i][j] > board[i][j - 1]) {                
                max = Math.max(max, findMax(i, j - 1, board));
            }
        }
        if (i + 1 < count.length) {
            if (board[i][j] > board[i + 1][j]) {                
                max = Math.max(max, findMax(i + 1, j, board));
            }
        }
        if (j + 1 < count[0].length) {
            if (board[i][j] > board[i][j + 1]) {                
                max = Math.max(max, findMax(i, j + 1, board));
            }
        }
        return count[i][j] = max + 1;
    }
}
http://lyeec.me/blog/POJ/POJ-1088/
用逆向思维,从低的点取值取到高的点。这样就不会漏掉状态了。
f[i][j]表示点(i,j)出发到可以到达的最高的点的距离。
所以搜索点(i,j)的时候,先搜索它周围的四个点,用它周围的四个点的f值更新(i,j)的f值。
也就是说如果h(i,j)<h(i±1,j±1)
那么f(i,j)=max(f(i,j),f(i±1,j±1)+1)
int f[200][200], h[200][200];
int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
int r, c;
int max(int a, int b) { return a > b ? a : b;}
int find(int, int);
int main() {
    scanf("%d%d", &r, &c);
    for (int i = 0; i < r; i++)
        for (int j = 0; j < c; j++)
            scanf("%d", &h[i][j]);
    int ans = 0;
    for (int i = 0; i < r; i++)
        for (int j = 0; j < c; j++)
            ans = max(ans, find(i,j));
    printf("%d", ++ans);
}
int find(int x, int y) {
    if(x < 0 || y < 0 || x >= r || y >= c) return 0;
    if(f[x][y] > 0)  return f[x][y];
    for (int i = 0; i < 4; i++)
        if(h[x + dx[i]][y + dy[i]] > h[x][y])
            f[x][y] = max(f[x][y], find(x + dx[i], y + dy[i]) + 1);
    return f[x][y];
}
X. BFS
http://my.oschina.net/Alexanderzhou/blog/203111
设一与输入数组对应的状态数组 dp,其值代表输入数组中此点的最长滑雪路径。使用广搜填表,最后遍历输出最大值即可。
const int MAX = 100; int map[MAX][MAX]; int dp[MAX][MAX]; int r, c; int BFS(int i, int j) { int max = -1; // 如当前坐标右侧有路,则广搜填值 if (j + 1 < c && map[i][j] > map[i][j + 1]) { if (dp[i][j + 1]) { max = max > dp[i][j + 1] ? max : dp[i][j + 1]; } else { max = max > BFS(i, j + 1) ? max : BFS(i, j + 1); } } // 向下广搜 if (i + 1 < r && map[i][j] > map[i + 1][j]) { if (dp[i + 1][j]) { max = max > dp[i + 1][j] ? max : dp[i + 1][j]; } else { max = max > BFS(i + 1, j) ? max : BFS(i + 1, j); } } // 向左广搜 if (j - 1 >= 0 && map[i][j] > map[i][j - 1]) { if (dp[i][j - 1]) { max = max > dp[i][j - 1] ? max : dp[i][j - 1]; } else { max = max > BFS(i, j - 1) ? max : BFS(i, j - 1); } } // 向上广搜 if (i - 1 >= 0 && map[i][j] > map[i - 1][j]) { if (dp[i - 1][j]) { max = max > dp[i - 1][j] ? max : dp[i - 1][j]; } else { max = max > BFS(i - 1, j) ? max : BFS(i - 1, j); } } // 如上下左右均不通,该点路径值为 1; // 否则取最大路径值加 1 if (max == -1) { dp[i][j] = 1; } else { dp[i][j] = 1 + max; } return dp[i][j]; } int solve() { // 遍历所有坐标,不留死角 int ans = 0; for (int i = 0; i < r; ++i) { for (int j = 0; j < c; ++j) { // 如尚未寻访此点,从此点向四面广搜 if (!dp[i][j]) { BFS(i, j); } // 同时记录最长路径 if (dp[i][j] > ans) { ans = dp[i][j]; } } } return ans; }
http://www.skymoon.biz/poj-1088%E9%A2%98-%E6%BB%91%E9%9B%AA/?variant=zh-tw
05int a[101][101],dp[101][101],n,m,x,y;
06int b[4][2]={-1,0,1,0,0,-1,0,1};
07int bfs(int x,int y)
08{   int s,t,max1;
09    if(dp[x][y]>1)return dp[x][y];
10    for(int l=0;l<4;l++)
11    {
12         s=x+b[l][0];t=y+b[l][1];
13         if(s>=0&&s<n&&t>=0&&t<m&&a[x][y]<a[s][t])
14        {    max1=bfs(s,t);
15            if((max1+1)>dp[x][y])
16             dp[x][y]=max1+1;
17         }
18    }
19    return dp[x][y];
20}
21int main()
22{
23    int T,i,j,k,l;
24          while(~scanf("%d%d",&n,&m))
25        {memset(a,0,sizeof(a));
26        for(i=0;i<n;i++)
27            for(j=0;j<m;j++)
28            {   scanf("%d",&a[i][j]);dp[i][j]=1;}
29        int max=0;
30        for(i=0;i<n;i++)
31            for(j=0;j<m;j++)
32            {
33                bfs(i,j);
34                if(dp[i][j]>max)
35                max=dp[i][j];
36            }
37            printf("%d\n",max);
38    }return 0;
39}
X. Greedy
 https://github.com/mccxj/codelab/blob/master/src/main/java/org/poj/Main1088.java
 * 方法1: 对所有位置的高度从小到大进行排序,从高度低的位置开始,计算它的最长滑雪路径(找周围高度比它小并且路径最长的,加1即可).
 * 使用贪心法,就可以计算出所有位置的最长滑雪路径,再从中找到个最大的就是结果.
     private static void run1() {
        Scanner cin = new Scanner(System.in);
        int r = cin.nextInt();// 行数
        int c = cin.nextInt();// 列数

        List<int[]> heights = new ArrayList<int[]>();// 用于对高度进行排序
        int[][] hs = new int[r][c];// 保留当前位置的最长滑雪路径
        int[][] hss = new int[r][c];// 保留当前位置的高度
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                hs[i][j] = 0;
                int h = cin.nextInt();
                hss[i][j] = h;
                heights.add(new int[]{h, i, j});
            }
        }

        // 对高度进行从小到大排序
        Collections.sort(heights, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[0] - o2[0];
            }
        });

        int mm = 1;
        for (int[] xx : heights) {
            int rr = xx[1];
            int cc = xx[2];
            int max = 0;

            // 找周围高度比它小并且路径最长的
            if (rr - 1 >= 0 && xx[0] > hss[rr - 1][cc] && hs[rr - 1][cc] > max)
                max = hs[rr - 1][cc];
            if (cc - 1 >= 0 && xx[0] > hss[rr][cc - 1] && hs[rr][cc - 1] > max)
                max = hs[rr][cc - 1];
            if (rr + 1 < r && xx[0] > hss[rr + 1][cc] && hs[rr + 1][cc] > max)
                max = hs[rr + 1][cc];
            if (cc + 1 < c && xx[0] > hss[rr][cc + 1] && hs[rr][cc + 1] > max)
                max = hs[rr][cc + 1];
            hs[rr][cc] = max + 1;// 更新当前位置的最长滑雪路径
            // 顺便记录当前环境下的最长路径
            if (hs[rr][cc] > mm)
                mm = hs[rr][cc];
        }
        System.out.println(mm);
    }
http://blog.csdn.net/enigma_hao/article/details/9183381
  • 先对数组中的数据进行排序,从最小的数据计算 当前的顶点的可以滑行的最大值=max(周围可达的顶点的可以滑行的最大值)+1
  • 这样计算最后产生的路径肯定是最大的 

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts