Recursive dynamic programming change

Recursion is an attempt, for example, I do not know the solution to a problem, but I know how to try.

God said Turing left the computer for is to try, before that, know all fixed solution to the problem, then use computers to solve. Therefore, it is known as the father of computers.

In fact, the earliest use of computers is Byron's daughter. The first female computer programmer oh.

 

P question: whether the solution of the problem can be determined in polynomial time

NP question: can be verified in polynomial time ( guess ) a solution of the problem.

NPC (NP- complete problem): 1, 2 is a NP problem, all NP problems can be reductive to it

Reductions (Reducibility, reduction): A problem can be reduced to a problem that is the meaning of B, A can solve the problem with the solution of the problem B, or that the problem can A "to" B. Issues "A problem can be reduced to the problem B" has an important intuitive meaning: B time complexity equal to or higher than the time complexity of A. Furthermore, the reduced transitive.

 NP-Hard problem: to meet the definition of Article NPC problem but not necessarily satisfy the first, all NP problems can be oriented about it, but he is not necessarily a NP problem.

 

Problem 1: Given two-dimensional array, from left to bottom right, down or right at each step only, the accumulated number of passes through, and returns the minimum path

 

Package Day6;
 / * 
 * a given two-dimensional array, from left to bottom right, down or right at each step only, 
 * accumulated number of passes through, and returns the minimum path 
 * 
 * (0,0) - ----> (n-, n-) 
 * / 
public  class Code06_PathMinSum {
     // recursive (double counting) 
    public  static  int getMin1 ( int ARR [] [], int I, int J, int SUM) {
         IF (I = arr.length == -1 && J = ARR [0] .length -1 ) { 
            SUM = ARR [I] [J]; 
        } 
        the else  IF (I arr.length == -1 ) { 
            SUMARR = [I] [J] + getMin1 (ARR, I, J +. 1 , SUM); 
        } 
        the else  IF (ARR == J [0] .length -1 ) { 
            SUM = ARR [I] [J] + getMin1 (ARR,. 1 + I , J, SUM); 
        } 
        the else {     
            SUM = ARR [I] [J] + Math.min (getMin1 (ARR,. 1 + I, J, SUM), getMin1 (ARR, I, J + . 1 , SUM)); 
        } 
        return SUM; 
    } 
    // dynamic programming 
    public  static  int getMin2 ( int ARR [] []) {
         // consider absence ah 
        IF (ARR == null || arr.length == 0 ARR || [0] == null || arr[0].length == 0) {
            return 0;
        }
        int n = arr.length -1;
        int m = arr[0].length -1;
        int  srr[][] = new int [n+1][m+1];
        for (int i = n ;i >=0 ;i--){
            for(int j = m ;j>=0 ;j--){
                if (i == n && j == m) {
                    srr[n][m] = arr[n][m];
                }
                else if(i == n) {
                    srr[i][j]=arr[i][j] + srr[i][j+1];
                }
                else if (j == m) {
                    srr[i][j]= arr[i][j] + srr[i+1][j];
                    
                }else {
                    srr[i][j] =arr[i][j]+ Math.min(srr[i+1][j],srr[i][j+1] );
                    
                }
            }    
        }
        return srr[0][0];
    }
    
    
    
    // for test
    public static int[][] generateRandomMatrix(int rowSize, int colSize) {
        if (rowSize < 0 || colSize < 0) {
            return null;
        }
        int[][] result = new int[rowSize][colSize];
        for (int i = 0; i != result.length; i++) {
            for (int j = 0; j != result[0].length; j++) {
                result[i][j] = (int) (Math.random() * 10);
            }
        }
        return result;
    }
    
    
    //test
    public static void main(String[] args) {
        int arr[][] = {
                {3,2,1,0,},
                {7,5,0,1,},
                {3,7,6,2,},
        };
        
        System.out.println(getMin1(arr,0,0,0));
        System.out.println(getMin2(arr));
        
        
        arr = generateRandomMatrix(6, 7);
        System.out.println(getMin1(arr,0,0,0));
        System.out.println(getMin2(arr));
        
        
    }

}

 

Problem 2: Given an array ARR [], and a number of AIM, selected from any number of arrays, and asked whether AIM obtained can accumulate, you can return true, false not return

Package Day6;
 / * 
 * Given an array ARR, and a number of AIM 
 * from the array to any selected number, and asked whether could accumulate obtained AIM, 
 * can return true, can not return to false 
 * / 
public  class Code07_CanGetAim { 
    
    public  static  Boolean canGetAim ( int ARR [], int AIM) {
         return   fun1 (ARR, 0, AIM, 0 ); 
        
    }     
    // recursive 
    public  static  Boolean fun1 ( int ARR [], int n-, int AIM, int SUM) {
         IF (= SUM = AIM) {
             return to true ; 
        } 
        IF (n-== arr.length) {
             return  to false ; 
        } 
        return fun1 (ARR,. 1 n-+, AIM, ARR + SUM [n-]) || fun1 (ARR,. 1 n-+ , AIM, SUM); 
    } 
    
    
    // dynamic programming 
    
    public  static  Boolean fun2 ( int ARR [], int AIM) {
         IF (ARR == null ) return  to false ;
         // preprocessing, the array may have positive numbers, may also have negative
         // range of sum minn ~ maxx maxx -minn total number +1 
         // corresponding to index (shift) coordinate min + 
        int maxx = 0, minn = 0;
        for (int i = 0 ; i < arr.length ;i ++) {
            if (arr[i] >0) {
                maxx += arr[i];
            }else {
                minn+= arr[i];
            }
        }
        if (aim >maxx || aim < minn) return false;    //保证aim在区间里
        
        int num =arr.length;
        int sum = maxx-minn;
        boolean dp[][] = new boolean[NUM +. 1] [+ SUM. 1 ];
         // System.out.println (Minn + "" + Maxx); 
        
        // a is an assignment, a is an assignment, the same effect
         // AIM is a number, the number becomes standard is -min 
        
        // DP [NUM] [AIM-Minn] = to true; 
        for ( int I = NUM; I> 0; i-- ) { 
            DP [I] [AIM -minn] = to true ; 
        } 
        

        
        for ( int NUM =. 1-I; I> = 0; i-- ) {
             for ( int J = 0; J <SUM; J ++ ) {
                 // J is the index number represents the j j + minn, the subscript variable + min             
                IF (J + ARR [I]> || J + ARR SUM [I] <0 ) {
                    dp[i][j]= dp[i+1][j]; 
                }else {
                    dp[i][j]= (dp[i+1][j] || dp[i+1][j+arr[i]]);
                }
                    
            }
        }
        
        return dp[0][0];
        
    }
    
    // for test
    public static int[] generateRandomMatrix(int maxSize, int maxValue) {
        if (maxSize < 0 ) {
            return null;
        }
        int[] result = new int[maxSize];
        for (int i = 0; i != result.length; i++) {
                result[i] = (int) (Math.random() * maxValue);
        }
        return result;
    }

    public static void  printArrays(int arr[]) {
        for (int i = 0 ; i< arr.length ; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
//        int arr[]= {3,2,7,13};//{3,2,1,-1};
//        int aim = 4;//9;
//        System.out.println(canGetAim(arr, aim));
//        System.out.println(fun2(arr, aim));
        int n =100,maxSize = 20,maxValue = 8,aim =44;
        boolean flag = true;
        for (int i = 0 ; i <n ; i ++) {
            int arr[] = generateRandomMatrix(maxSize, maxValue);
            if(fun2(arr, aim) != canGetAim(arr, aim)) {
                flag = false;
                printArrays(arr);
                System.out.println(canGetAim(arr, aim));
                System.out.println(fun2(arr, aim));
                break;
            }
        }
        System.out.println(flag ? "Nice!":"WOw!!!!Problem show up !!!!!!!"); 
        
    }
}

 

 

Dynamic programming can return dp [0] [0] before cycle for replacing the following, the same effect, more concise. This is the core code. Comparable recursion.

        // write more concise, the same reason 
        for ( int I =-NUM. 1; I> = 0; i-- ) {
             for ( int J = SUM; J> = 0; J,) { // Note here j must forward from the rear
                 // j is the index, j represents the number j + minn, the subscript variable min +                 
                DP [I] [j] DP = [I +. 1 ] [j]; 
                 IF (j + ARR [ I] <= SUM && J + ARR [I]> = 0 ) { 
                    DP [I] [J] = (DP [I] [J] || DP [I +. 1] [J + ARR [I]]); 
                }                 
            } 
        }

 

 Summary - recursive change the dynamic programming:

One, conditions

  1, there is repeated the state of

  2, no after-effects problem. That is path-independent state (after reaching this state, no matter how reach this state, regardless of the way to go back in front. This is similar to the door, Cheng pulls back to make cut off), Furthermore, after determining variable parameters, return value is determined.

Second, a method (routine)

  1, in accordance with the requirements to write recursive version

  2, find the location needs to be resolved

  3, back basecase, the position will not be dependent set (such as the title 2 is the last line)

  4, return to normal position (situation), find dependencies.

Guess you like

Origin www.cnblogs.com/codinghard/p/11510828.html