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.