A case study of dynamic programming
If we have a number of coins with a nominal value of 1 yuan, 3 yuan and 5 yuan, how can we use the least coins to gather up 11 dollars? (On the surface of this problem can use greedy algorithm, but the greedy algorithm can not guarantee to find solutions, such as 1 yuan to 2 yuan when)
First we think about a problem, how to use the smallest coins to gather up the I-yuan (i<11). Why would you ask that? Two reasons: 1. When we have a big problem, we always get used to making the problem smaller and easier to analyze and discuss. 2. The size of the problem and the original problem is homogeneous, in addition to small size, the other is the same, in essence it is still the same problem (small size after the problem is actually the original problem of the child).
OK, let's start with the smallest I. When the i=0, that is, how many coins we need to scrape together enough 0 yuan. Because the 1,3,5 are more than 0, that is, there is no more than 0 small value, so together enough 0 yuan we need at least 0 coins. (This analysis is silly, isn't it?) Don't worry, this idea will help us to clarify what dynamic planning is doing. This time we found a sign to indicate that "we need at least 0 coins to scrape up 0 dollars." "will be more convenient, if you have been using plain words to express, in a moment you will feel very winding." So, we use D (i) =j to indicate that I need at least J-coins to scrape together enough. So we've got D (0) = 0, which means a minimum of 0 coins to scrape up 0 yuan. When I=1, only a coin with a face value of 1 yuan is available, so we pick up a coin with a value of 1, and then just have to scrape up 0 yuan, which is already known, that is, d (0) = 0. So, d (1) =d (1-1) +1=d (0) +1=0+1=1. When i=2, still only 1 coins are available, so I picked up a coin with a face value of 1, then I just need to make up 2-1 = 1 yuan (remember to use the smallest number of coins), and this answer has already known. So D (2) =d (2-1) +1=d (1) +1=1+1=2. All the way to here, you may feel, so boring, feeling like a pupil's topic. Because we've always been able to manipulate coins with a nominal value of 1. Be patient, let's look at the i=3. When i=3, we can use two kinds of coins: 1 Yuan and 3 yuan (5 yuan is still useless, because you need to gather the number is 3 yuan. 5 Yuan too many pro). Since there are two kinds of coins that can be used, I have two options. If I take a 1-dollar coin, my goal will be: scrape up enough 3-1 = 2 dollars to the minimum number of coins needed. That is, D (3) =d (3-1) +1=d (2) +1=2+1=3. The plan says, I take 3 coins of 1 yuan; the second option is that I pick up a 3-dollar coin and my goal is to: scrape up the minimum number of coins needed for 3-3 = 0 yuan. That is, D (3) =d (3-3) +1=d (0) +1=0+1=1. This proposal says, I take 1 coins of 3 yuan. Well, which one of these two schemes is better. Remember that we have to use the smallest number of coins to gather enough 3 yuan. So, choose D (3) = 1, how do you get here? This is achieved by: D (3) =min{d (3-1) +1, D (3-3) +1}.
<span style= "color: #333333;"
>package COM.DP; </span><span style= "color: #ff0000;" >//should be able to optimize, ask the great God advice </span><span style= "color: #333333;"
> public class Theminestcoin {/** * @param args *///Dynamic planning the value derived from the previous correlation, that is, the solution of the current child problem from the previous issue, migrated from the previous state to the current state, affected by the previous state
This is the essence of the Branch law. The sub-problem of the rule without State migration is not affected by the preceding result * * When the coin is zero * d (0) =0 * d (1) =d (1-1) +1 * d (2) =d (2-1) +1 * d (3) =d (3-1) +1
* d (3) =d (3-3) +1;
* d (3) =min{d (3-1) +1,d (3-3) +1};//The minimum value of the number of coins dynamic programming/public static void main (string[] args) {int a[] = {1, 3, 5};
Need at least a few coins int count=11;
Numberofcoin (A, count); private static void Numberofcoin (int[] A, int count) {int min[]=new int[count+1];//the minimum number of coins needed to store the coin min[0]=0;//i
NT mincoin=0;//for (int i=1;i<min.length;i++) {mincoin=i;//i is immutable, each one is related to the previous/* * To find the number of the smallest coins * * for (int j=0;j<a.length;j++) {if (a[j]<=i && min[i-a[j]]+1<mincoin)//here </span><span sty Le= "Color:rgb (51, 51, 51); Font-family: ' Helvetica neue ', Helvetica, Arial, Sans-serif; >d (3) =min{d (3-1) +1,d (3-3) +1}</span><span style= "color: #333333;"
> {mincoin=min[i-a[j]]+1;
} System.out.println (Mincoin + "i=" +i);
min[i]=mincoin;//time complexity of O (n^2)} System.out.println (min[11)); }} </span>
Instance 2 the longest increment subsequence of dynamic programming
<span style= "FONT-SIZE:14PX;"
>package COM.DP;
The public class Thelargestincreamentsubstring {/** * hypothesis sequence is 5,3,4,8,6,7 * d (0) = 1;
* d (1) = 1; because 5>3 * d (2) =d (1) +1;4>3 * d (3) =d (2) +1;
* D (4) = 1; because 6<8;
* d (5) =d (4) +1; because 7>6 * then the maximum increment subsequence is d (i) = Max{1, D (j) +1}, where j<i,a[j]<=a[i];
* */public static void main (string[] args) {int a[]={5,3,4,8,6,7};//int lis[]=new int[a.length];//all are negative.
for (int i=0;i<a.length;i++) {lis[i]=1;
for (int j=0;j<=i;j++) {if (A[j]<a[i] && lis[j]+1>lis[i]) {lis[i]=lis[j]+1;
}} int max=lis[0];
for (int i=1;i<lis.length;i++) {if (Lis[i]>max) {max=lis[i];
} System.out.println (max);
Time Complexity of O (n^2);
Optimized LISS (a);
} private static void LISS (int[] a) {//The previous order lookup, we have changed to two-point lookup, so that we can reduce the complexity of time to Nlogn int lis[]=new int[a.length];
lis[0]=-10000;//assumes that all elements in the array are larger than the number (number of identifiers) lis[1]=a[0];//at the start of int low,mid,high;
int len=1; for (int i=0;i< a.length;i++) {low=0;
High=len;//lis array The current array has the actual length of elements 0 and 1 while (Low<=high) {mid= (Low+high) >>1;
if (A[i]>lis[mid]) {low=mid+1;
}else {high=mid-1;
}} Lis[low]=a[i];
if (Low>len) len++;
for (int i=1;i<=len;i++) {System.out.print (lis[i]+ ""); } </span><span style= "FONT-SIZE:24PX;" "} </span>
3. Maximum sub Array and
public class Thelargestsubhe {
/**
* @param args
*
/public static void main (string[] args) {
//int a[ ]={-5,2,7,-4,10,3,-2,1};
int a[]={1,-2,3,10,-4,7,2,-5};
Maxsubsum (a);
}
private static void Maxsubsum (int[] a) {
int nall=0,ntotal=0;
for (int i=0;i<a.length;i++)
{
Ntotal=max (ntotal+a[i],a[i]);
Nall=max (Ntotal,nall);
}
System.out.println (Nall);
}
private static int Max (int i, int j) {
//TODO auto-generated method stub return
i>j?i:j;
}
}
Longest common child sequence
The introduction of a two-dimensional array c[][], using c[i][j] to record the length of the LCS of X[i] and Y[j, B[i][j] Records c[i][j is obtained by the value of which child problem to determine the direction of the search.
We are recursive computations from the bottom up, then the c[i-1][j-1],c[i-1][j] and c[i][j-1] are calculated before the c[i,j is computed. At this point, we can calculate the y[j according to x[i] = Y[j] or x[i]!= c[i][j].
Recursive type
Graphic
public class Thelargestcommonmehtod {static int count = 0;
public static void Main (string[] args) {String a = "Abcbdab";
String B = "Bdcaba";
int c[][] = new Int[a.length ()][b.length ()];
The longest common subsequence is instead of the longest common substring Thelcs (a, B, c);
Print output longest common subsequence println (A.length ()-1, B.length ()-1, A, c);
System.out.println ("*******************************");
for (int i=1;i<c.length;i++) {for (int j=1;j<c[0].length;j++) {System.out.print (c[i][j]+ "");
} System.out.println ();
}} private static void println (int i, Int J, String A, int[][] c) {if (i = = 0 | | | j = = 0) return;
if (c[i][j] = = 1) {println (i-1, J-1, A, c);
System.out.print (A.charat (i) + "");
} if (c[i][j] = = 2) {println (i-1, J, A, c);
else if (c[i][j]==3) {println (I, J-1, A, c);
} private static void Thelcs (string A, string B, int[][] m) {//System.out.println (A.length ()); if (a = = NULL | | | b = NULL | | a = = "" | |
b = = "") return;int c[][] = new Int[a.length ()][b.length ()];//default values are 0//The first element is ignored by default from 1, so I added a space in the string that represents the first same but does not participate in the result for (int i = 1; I < a.length (); i++) {for (int j = 1; J < B.length (); j + +) {if (A.charat (i) = = B.charat (j)) {C[i][j] = C[i-1][j-1] +
1;
M[I][J] = 1;
else if (C[i-1][j] > C[i][j-1]) {c[i][j] = c[i-1][j];
M[I][J] = 2;
else {C[i][j] = c[i][j-1];
M[I][J] = 3; (int i = 1; i < a.length (); i++) {for (int j = 1; J < B.length (); j + +) {System.out.print (c I
[j] + "");
} System.out.println (); }
}
}