A summary of dynamic programming algorithms

Source: Internet
Author: User
Tags first string min split strlen first row

Dynamic programming algorithm, in the T-Big Teacher's book that is recursive + repeating sub-problem.

The efficiency of dynamic programming algorithm is mainly related to the processing of repetitive sub-problems.

Typical topics have a jury, the biggest common substring problem

1, maximum common substring problem

This is the basic topic of dynamic programming. Dynamic programming is the recursive and repeating substructure.

After the recurrence relationship has been determined. It is important to find a sub-structure that greatly reduces the repetition operation. The choice is good, the time efficiency will be very good.

This problem, it is advisable to set the first string as a, the length is N, the second string is B, the length m. Then the longest subsequence length is f (n,m)

When A[n]=a[m]

F (n,m) =1+f (n-1,m-1)

Otherwise f (n,m) =max (f (n-1), F (m-1))

Create a matrix that stores the computed f (x, y), and use it directly if it is calculated

The program is shown below

#include <iostream> #define MaxLen + char Seq1[maxlen]; Char Seq2[maxlen]; int Maxlen[maxlen][maxlen]; int Maxcommonmain () {while (scanf ("%s%s", seq1+1,seq2+1) >0) {int Length1=strlen (seq1+1); int Length2=strlen (seq2+1) ; for (int i=0;i<=length1;i++) maxlen[i][0]=0; for (int j=0;j<=length2;j++) maxlen[0][j]=0; for (int i=1;i<=length1;i++) {for (int j=1;j<=length2;j++) {if (Seq1[i]==seq2[j]) maxlen[i][j]=maxlen[i-1][j-1]+ 1; else maxlen[i][j]=maxlen[i-1][j]>maxlen[i][j-1]?maxlen[i-1][j]:maxlen[i][j-1]; }} printf ("%d/n", Maxlen[length1][length2]); printf ("%d", maxlen[length2-1][length1-1]); } return 0; }

2, jury questions

Problem Description:

Problem description
It is up to the jury to decide whether the suspect is guilty in a distant country Frobnia. The jury was made by the judge from the public
Selected. A random selection of N-individuals as a jury candidate, and then from the N-person selected m people to form a jury.
The way to choose m people is:
The prosecution and the defence will rate all candidates based on their liking for the candidate, with a score of 0 to 20. For the public
For the sake of fairness, the judge elects the jury by the principle that the selected m-person must satisfy the difference between the defense's total score and the overall control score.
The absolute value is minimal. If there are multiple options with the same absolute value of the difference between the defense score and the control score, then the selection of the defence
The maximum sum of the two sides of the scheme can be. The final option is called a jury program.
Input data
The input contains multiple sets of data. The first row of each group of data is two integers n and m,n is the number of candidates, M is the jury
Group size. Note, 1<=n<=200, 1<=m<=20 and M<=n. Next n rows, each line represents a candidate
Information, which contains 2 integers, which is the rating of the candidate by both the prosecution and the defence. Candidates by the appearance of the succession from 1
Start numbering. Two valid sets of data are separated by a blank line. The last set of data n=m=0
Output requirements
For each set of data, the first line is output, indicating the group number to which the answer belongs, such as ' Jury #1 ', ' Jury #2 ', and so on. The next
One line will output the jury's total and defense totals as examples. And then down one line to output the jury in ascending order every
Number of members, separated by a space between two member numbers. Each set of output data must end with a blank line.
Input sample
4 2
1 2
2 3
4 1
6 2
0 0
Output sample
Jury #1
Best jury have value 6 for prosecution and value 4 for defence:
2 3

Using dynamic programming to solve

Dynamic programming can be seen as repeating sub-problems + recursion

Set p as the direction of control, D for the direction of the argument

Score from 400 to 400
F (j,k) for the selection of the person J, the score difference is K of the total defense score
For any i,i greater than 0 is less than N, there is
F (j,k) =f (J-1+1,x+p[i]-d[i])
Then there is
F (j,k) =f (j-1,x) +p[i]+d[i];

If the new F (j,k) is larger than the old, then replace the old, otherwise do not replace

The initial value is k=0, which may be a value in the program to avoid negative values in the ordinal K.
So the initial f (0,0) = 0;
In the first round there was only a reasonable argument for the difference of 0
For all the candidates to do
F (1,p[i]-d[i]) =max (f (1,p[i]-d[i]), F (0,0) +p[i]+d[i]);
This allows you to complete the selection of a person's operation.
The most recent non-negative from k=0 is the biggest defense we have to make. The subscript is the difference between the accused and the defendant.
Similarly, if you choose Two, the second round
k=-400~400
If f (1,k) is reasonable (at this point, it is only reasonable in the first round)
F (2,k+p[i]-d[i]) =max (f (2,k+p[i]-d[i]), F (1,k) +p[i]+d[i]);

If you want to save the path you have searched for
Set path paths save path vector
Path (J,K) saves a candidate who is recommended to be a J-juror when he or she argues for the difference.
corresponding to the F function above, the initial value is set to 0.
If only one candidate is found
There is no value in the path itself, that is, no one is recommended. In other words, when recommending the first person, who can (if recommend a second person, the previously recommended can not be recommended again)
When recommending the first candidate, save Path[0][p[i]-d[i]]=i;

When selecting multiple candidates, update the path while updating F (j,k), since updating F (j,k) means selecting a new candidate, so you need to update the path


When the above is done,
define an array of result to fetch the path
to I:1~m
 result[i]=path[m-i+1][k];
 k=k-p[result[i]]+d[ Result[i]];
This is all resolved.

#include <stdlib.h> #include <iostream> #include <memory.h> int p[300]; int d[300]; int path[30][1000]; int f[30][1000]; int result[30]; int compareint (const void *el, const void *e2) {return * (int *) EL)-* ((int *) e2);} int Jurymain () {int n,m; scanf ("%d%d ", &n,&m); int no=0; int i=0; while (n+m)//n=0,m=0 end condition {no++; for (i=1;i<=n;i++) scanf ("%d%d", &p[i],&d[i]); Memset (F,-1,sizeof (f)); memset (path,0,sizeof (path)); int mind=20*m; f[0][mind]=0; for (int j=0;j<m;j++) {in (int k=0;k<=mind*2;k++) {if (f[j][k]>=0) {i=1; int temp1; int temp2; for (; i<=n;i++) {if (F[j][k]+p[i]+d[i]>f[j+1][k+p[i]-d[i]]) {temp1=j; temp2=k; while (temp1>0&&path[temp1][temp2]!=i) {TEMP2=TEMP2-P[PATH[TEMP1][TEMP2]]+D[PATH[TEMP1][TEMP2]]; temp1--;} if (temp1==0) {f[j+1][k+p[i]-d[i]]=f[j][k]+p[i]+d[i]; path[j+1][k+p[i]-d[i]]=i;}} }}}} I=mind; int j=0; int k=0; while (f[m][i+j]<0&&f[m][i-j]<0) j + +; if (F[m][i+j]>f[m][i-j]) k=i+j; else k=I-j; printf ("Jury #%d/n", no); printf ("Best jury have value%d for prosecution and value%d for defence:/n", (K-mind+f[m][k])/2, (Mind-k+f[m][k])/2); for (i=1;i<=m;i++) {result[i]=path[m-i+1][k]; K-=p[result[i]]-d[result[i]];//std::cout<< "result" << i<< "" <<result[i]<<std::endl;} Qsort (result+1,m,sizeof (int), compareint); for (i=1;i<=m;i++) printf ("%d", result[i]); printf ("/n/n"); scanf ("%d%d", &n,&m); }//system ("pause"); return 0; }  

3, Floret shop problem

F bouquet of flowers from left to right in the V vase inside (1<=f<=v<=100), flowers to follow the number of signs of flowers from small to large arrangement. Different flowers in different vases can produce different aesthetic values. V[I,J] to represent the aesthetic value of the first flower in the first J Vase. The greatest aesthetic value that can be produced by placing n flowers in M vases.

This question is similar to the thinking angle of the largest common substring. Because the flower must be less than or equal to the bottle. And the number of flowers from small to large, can not disorderly order. For example, the phenomenon of "2,4" and "1,5" cannot be seen. That is to say, the flowers inserted in the vase are arranged in ascending order according to the vase sequence.

Use F (i,j) to insert the front I flower into the previous bottle. When I=j, F (i,j) =v[1,1]+v[2,2]+...+v[i,i];

When I=0, f (0,j) = 0; When I!=j, and i!=0 F (i,j) =max (f (i,j-1), F (i-1,j-1) +v[i,j]), i<=j-1.

#include <stdlib.h> #include <stdio.h> void getmaxvalue (int **f,int **v,int m,int N) {for (int j=1;j<=m;j++ {for (int i=1;i<=j-1;i++) {if (f[i-1][j-1]+v[i][j]>f[i][j-1]) f[i][j]=f[i-1][j-1]+v[i][j]; else f[i][j]=f[i][ J-1]; }}} int main () {int n,m; scanf ("%d%d", &n,&m); int **v=new int[n+1][m+1]; int **f=new int[n+1][m+1]; v[0][0]=0; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf ("$d", V[i][j]); for (int j=0;j<=m;j++) v[0][j]=0; int tempsum=0; for (int i=0;i<=n;i++) {sum+=v[i][i]; f[i][i]=sum;} getmaxvalue (F,v,m,n); Delete (v); return 0; }

4, Best travel line problem

Brief description: A prize from an airline, a free ticket. From one of the most western cities, you must reach the easternmost city and then return to the beginning of the city. Each city function passes once and the starting point is accessed 2 times. How many cities can be visited at a maximum.

This topic can be used in a dynamic programming approach. This topic also reminds me of the "Introduction to the algorithm" in the assembly line problem, in fact, is basically consistent.

In many books or solutions, the method is used: Starting from the beginning, two roads together f[i,j] means that two disjoint routes to I and J, the maximum number of routes required

F (a) = 0;

F (i,j) = Max{f (K,j)}+1,i>j; k is the precursor node of I.

Max{f (i,k)}+1,i<j

F (i,i) meaningless

The algorithm is not wrong. Many places also use this algorithm to do some version of the program. But there is a limit to this algorithm, which is the precursor node. In the book of the T-Big teacher, he enumerates all the point pairs and then updates the F-matrix (the traditional dynamic programming method). But he has a premise, that is, the sequence number of all nodes conforms to the topological sequences. But the problem does not say that cities conform to topological sequences. If the serial number is more random, the T-Big Book is wrong. But he did not describe it in the code as a misleading to the reader.

#ifndef ticketaward_h #define TICKETAWARD_H class Ticketaward {int *b;//degrees int **g;//g (I,J) The first point of the J child int **f;//function f int n;//a total of n nodes Public:ticketaward (); int max (int x,int y); }; #endif

#include "stdafx.h" #include <iostream> #include "TicketAward.h" Ticketaward::ticketaward () {std::cin>>n; g=new int *[n+1]; B=new int[n+1]; F=new int*[n+1]; for (int i=1;i<=n;i++) {g[i]=new int[n+1], f[i]=new int[n+1]; b[i]=0; for (int j=1;j<=n;j++) {}} int temp=0; for (int i=1;i<=n;i++) {std::cin>>temp;//Enter the first child of I, if not 0, that is, the child node is present, then continue while (temp!=0) {b[i]++; g[i][b[i]]= Temp std::cin>>temp; }} f[1][1]=0; for (int i=1;i<=n;i++) {for (int j=1;j<=b[i];j++) {if (i==j==1) continue, if (I<J) for (int k=1;k<=b[i];k++) {f[ I][j]=max (F[i][j], (f[g[i][k]][j]+1)); } if (I>J) for (int k=1;k<=b[j];k++) {F[i][j]=max (F[i][j], (f[g[j][k]][j]+1));}} } std::cout<< (F[n][n]-2); } int Ticketaward::max (int x, int y) {return x>y?x:y;}

5, the longest word chain problem

Given a list of English words that contain only lowercase letters, each word contains at least one letter, with a maximum of 75 letters, arranged in a dictionary order. All words contain no more than 200w of the number of words

If, in a table consisting of one word or multiple words, each word is contained by a word that follows, the table is a chain.

It is now required to find the longest word chain containing the most word books from the word list.

The problem can be solved by dynamic programming. It reminds me of a question: in a continuous long string, find the phrase with the most number of matches and cannot overlap. The same method.

The longest chain that makes F (k) represent the time of the K-word. Then f (k) =maxf (i) +1,i from 1, to K-1, and the first word is a prefix of K. The problem is solved here.

However, there are other solutions to this problem. Because the dictionary order is not chaotic. The prefix contained in the previous word of each word is likely to be the prefix of the word, and the previous word may be the prefix for that word. Because of the particularity of the prefix. So just check the prefix of the previous word (including the word itself) to find the prefix chain

Code is a non-dynamic programming algorithm

#include "stdafx.h" #ifndef mostlengthletter_h #define MOSTLENGTHLETTER_H #include <iostream> #include <string > struct Pnode {int len; Pnode *next[26]; }; struct Mostlengthletters {public:mostlengthletters () {for (int i=0;i<=25;i++) {root.next[i]=null;} ans=0; std::cout << "Please input the num of words" <<std::endl; std::cin>>wordsnum; This->getwords (); } void Getwords (); void update (std::string temp); int wordsnum; Pnode Root; int ans; }; void Mostlengthletters::getwords () {std::string temp; for (int i=0;i<this->wordsnum;i++) {std::cin>>temp; This->update (temp); }} void Mostlengthletters::update (std::string temp) {int len=temp.length (); Pnode P=root; int max=0; int i=1; int tempint=0; while (I<len) {tempint=temp[i]-' a ', if (p.next[i]==null) {pnode *node=new pnode; node->len=0; for (int j=0;j<=25 ; j + +) {node->next[j]=null;}} if (Max<p.len) Max=p.len; i++; P=*p.next[tempint]; } p.len=max+1; this->ans=p.len; ReturN } #endif

6, Integer partitioning problem

Given a natural number, divided into k parts, a1,a2. The number of the and, requirements a1<=a2 ... Ask how many kinds.

Principle: integer n is split into a maximum of no more than M and the split fraction, and N split into a maximum of not more than M of the split fraction equal. According to this principle, the original problem is converted to the maximum split into K split number and the largest split divided into k-1 of the difference F (n,k) =f (n,k-1) +f (n-k,k). #include "stdafx.h" #ifndef splittoknum_h #define Splittoknum_h #include <iostream> #include <memory.h> # Define MAXN class Splittoknum {public:splittoknum () {std::cin>>n; std::cin>>k; memset (f,0,sizeof (f)); F or (int i=1;i<=k;i++) {f[maxn][i]=1;} for (int j=1;j<=k;j++) for (int i=maxn+1;i<=maxn+n;i++) f[i][j]=f[i][j-1] +F[I-J][J]; std::cout<<f[n+maxn][k]-f[n+maxn][k-1]<<std::endl; } int n; int k; int F[2*MAXN+1][MAXN]; }; #endif also attached to the several principles of the Ferrer diagram: A, integer n split into the sum of k number of split fractions, and N split the maximum number of K of the split fraction of equal B, the integer n split into a maximum of not more than m number of the sum of the split fraction, and N split into a maximum of not more than M split fraction equal. c, the integer n is split into a number of different odd and split fractions, and N is split into a self-conjugate Ferrers image of the split fraction equal.

7, the Frog's troubles

In the pond there are n pieces of lotus, just form a convex polygon, according to the clockwise direction of the n pieces and also sequentially numbered 1,2,3,4,5...,n. A frog wants to skip these lotus leaves, each can only be skipped once, hoping to skip the shortest distance.

Enter the number of Lotus leaf n, the coordinates of each lotus leaf xy, output the shortest distance.

Analysis: Convex polygon, the first can not appear intersection, otherwise, by the sum of the two sides is greater than the third side to know, so it is actually a longer distance.

Secondly, directly according to the convex polygon is also not correct, you can refer to parallelogram, one of the angle of 30 degrees, please draw your own to find out.

Method: Each vertex can only reach one of the two adjacent to itself (intersecting with other vertex edges), and the remaining n-1 vertices follow this rule. You can use the method of dynamic planning.

From S to l

If starting from S, then F (s,l,0) =min{dis (s,s+1) +f (s+1,l-1,0), F (s+1,l-1,1) +dis (s+l-1,s)}

If departing from S+l-1 F (s,l,1) =min{dis (S,S+L-1) +f (s+l-1,l-1,0), F (s+l-1,l-1,0) +dis (s+l-1,s)}

#include <stdlib.h> #include <stdio.h> #include <iostream> #define MAXN double x[maxn];//x Radix D Ouble Y[MAXN]; Double DIS[MAXN][MAXN]; int n;//The num of double f[maxn][2][2]; Double min (double a,double b) {return a<b?a:b;} int main () {std::cout<< "Please input the num of the points" &lt ;<std::endl; std::cin>>n; for (int i=0;i<n;i++) {std::cin>>x[i]>>y[i];} for (int. i=0;i<n-1;i++) {for (int j=i+1;j<n;j++) {dis I [J]= (X[i]-x[j]) * (X[i]-x[j]) + (Y[i]-y[j]) * (Y[i]-y[j]); DIS[J][I]=DIS[I][J]; }} int sign=0; Double ans=1000000; for (int j=1;j<=n;j++) {sign=1-sign, for (int i=n-1;i>=0;i--) {if (j==1) {f[i][sign][0]=0; f[i][sign][1]=0;} else { F[i][sign][1]=min (f[(i+1)%n][1-sign][1]+dis[i][(i+1)%n],f[(i+1)%n][1-sign][0]+dis[i][(i+j-1)%n]); F[i][sign][0]=min (f[i][1-sign][1]+dis[(i+j-1)%n][i],f[i][1-sign][0]+dis[(i+j-1)%n][(i+j-2)%n]); } if (j==n) ans=min (ans,f[i][sign][1]); }}//std::cout<<f[1][sign][1]<< "/t" &Lt;<f[1][sign][0]<<std::endl; std::cout<<ans<<std::endl; return 0; }

8 Permutation questions

In integers 1, 2, ... , n, some permutations satisfy the following properties: In addition to the last digit in the arrangement, each integer is followed by an integer that has a difference of 1 from it. For example: n=4, arrangement 1432 satisfies the above-mentioned properties. If any value of P position is specified, the maximum number of permutations satisfies the above properties

This arrangement satisfies two properties

A, the post K bit of any permutation is a collection of several consecutive integers

b, if an arranged post K-bit (1<=k<=n) is a set of soft-dry continuous integers, then this arrangement satisfies the nature of the topic.

The method of dynamic planning can be. Set S to the size of the starting number, and R for the number of consecutive numbers

The

G (S,r) =g (s+1,j-1), if the 1th position is s, that is, the countdown J position is S

G (s,j-1), if the 1th position is s+r-1, that is, the inverse of the J position is s+r-1

Uncertainty is the sum of the above two

The code is as follows

#include <stdlib.h> #include <iostream> #include <memory.h> class Rankprogram {Public:rankprogram () { std::cout<< "Please input the testing data" <<std::endl; std::cin>>n>>p; S=new int[n+2]; G=new int* [n+2]; for (int i=0;i<=n+1;i++) {g[i]=new int[n+2]; memset (g[i],0,sizeof (int) * (n+2)); g[i][1]=1;} memset (s,0,sizeof (int) * (n+2)); int tempdata; int tempp; for (int i=1;i<=p;i++) {std::cin>>tempp>>tempdata; s[n-tempp+1]=tempdata,} for (int i=n;i>=1;i--) { for (int j=2;j<=n-i+1;j++) {if (s[j]==i) g[i][j]=g[i+1][j-1], else if (s[j]== (i+j-1)) g[i][j]=g[i][j-1]; else g[i][j]= G[I+1][J-1]+G[I][J-1]; }} std::cout<<g[1][n]<<std::endl; } ~rankprogram () {delete [] s; for (int i=0;i<=n+1;i++) Delete [] g[i]; delete [] g;} private:int *s; int **g; int p; int n; }; int main () {Rankprogram rp;}

9, Studio problem

In fact, the problem can be described as, given a matrix of size N, row and column width is 2^n, the matrix is divided into 4 points, the upper left corner is not zero, the other three parts contain 0. Recursively defines these three parts until the smallest unit, that is, the matrix has only one number, which is 0;

If you let the Matrix move one dimension (x, y), the number of 0 of the repeating portion of the two matrix.

Thinking: In fact, it is to determine whether the position before and after the move is 0, if all is 0, then the total 0 number +1.

If you move to the upper-left corner, the other three parts are the same, and the part recursively defines the upper +1

In the following program, K1,K2 represents the position, which piece of the current region

A, B represents three regions, where the upper left is ignored directly.

KK1,KK2, which area is moved to

if (! ( (A+P[I-1]+K1)%2==0&& (B+Q[I-1]+K2)%2==1) indicates which piece of the area to move to, and if it is ignored directly on the left

#ifndef matrixmove_h #define Matrixmove_h #include <iostream> #include <memory.h> #define MAXN 101 Class Matri Xmove {public:matrixmove () {std::cin>>n; memset (f,0,sizeof (f)); f[n+1][0][0]=1; f[n+1][0][1]=f[n+1][1][0]=f[n +1][1][1]=0; std::cin>>x>>y; for (int i=1;i<=n;i++) {p[n-i+1]=x%2; q[n-i+1]=y%2, X=X/2; y=y/2;} for (int i=n+1;i>=2;i--) {for (int k1=0;k1<=1; k1++) for (int k2=0;k2<=1;k2++) for (int a=0;a<=1;a++) for (int b=0;b<=1;b++) {if (!) ( a==0&&b==1)) {int kk1= (A+P[I-1]+K1)/2; int kk2= (B+Q[I-1]+K2)/2; (A+P[I-1]+K1)%2==0&& (B+Q[I-1]+K2)%2==1) {F[I-1][KK1][KK2]+=F[I][K1][K2];}} }} std::cout<<f[1][0][0]<<std::endl; } private:int N; int x; int y; int f[maxn][2][2]; int P[MAXN]; int Q[MAXN]; }; #endif

10, Medieval Swordsman

n personal duel, 22 have strong and weak relations, strong and weak relations do not pass, such as A>b,b>c,c>a. n a sword in a circle, a lottery, the people in the smoke and his right to duel, the loser out of the circle. Now ask if there is a duel way for the K-man to give birth and calculate the number and scheme of possible winners.

This topic reminds me of the question of a monkey in a circle, the subject of which is Joseph.

It's not like this.

This topic: A person to win, you have to win all the right people, but also to win the people on the left. Because it is surrounded by a circle, so the person wins, the final must be himself and meet with himself. So, in this case, expand the circle into a chain, extend the chain one more time, if I and i+n can meet, then I can win. I fight to the right, i+n to the left.

If two people can meet, use meet[i,j] to express

meet[i,j]= true if MEET[I,K] and Meet[k,j] and (E[i,k] or e[j,k]) =true

False

#ifndef acientsoldier_h #define Acientsoldier_h #include <iostream> #include <memory.h> class Acientsoldier {Public:acientsoldier () {std::cin>>n; a=new int*[n+1]; meet=new bool*[2*n+1]; for (int i=1;i<=n;i++) {a[i]=new INT[N+1]; Meet[i]=new bool[2*n+1]; Meet[i+n]=new bool[2*n+1]; memset (meet[i],0,sizeof (BOOL) * (2*n+1)); memset (meet[i+n],0,sizeof (BOOL) * (2*n+1)); Meet[i][i+1]=true; Meet[i+1][i]=true; meet[i+n][(i+n)%2+1]=true; meet[(i+n)%2+1][i+n]=true; for (int j=1;j<=n;j++) std::cin>>a[i][j]; } for (int k=1;k<=2*n;k++) for (int i=1;i<=2*n;i++) for (int j=1;j<=2*n;j++) {if (i<k) && (j>k) &&meet[i][k]&&meet[k][j]&&a[(i-1)%n+1][(k-1)%n+1]&&a[(j-1)%n+1][(k-1)%n+1]) { Meet[i][j]=true; Meet[j][i]=true; }} ans=0; for (int i=1;i<=n;i++) {if (meet[i][i+n]) ans++;} std::cout<<ans<<std::endl;; } private:int N; int **a; BOOL **meet; int ans; }; #endif

11, scientists experiment with meteorites

A total of N1 block a star and N2 block B star, each experiment needs a piece, after the experiment can not be recycled.

Total Experiment min (n1,n2);

To find the absolute value of each test and the minimum

First, prove it. Two ascending sequences, A1<B1,A2<B2, |a2-a1|+|b2-b1|<=|b2-a1|+|b1-a2|

------A1----------------B1-------------

- -

-

O

------A2----------------B2--------------

The above figure can be directly proved by the sum of the two edges greater than the third side.

So you can confidently use dynamic planning.

The two columns of data from small to large sort, less with I, more in the J to indicate

F[i,j]=min (F[i,j-1],f[i-1][j-1]+dis (i,j)) j>i

F[i-1][j-1]+dis (I,J) j=i

Programming temporarily omitted, because this topic is relatively simple

12, the ideal income problem

Only one yuan of the principal, know the daily stock price of v[i], for the ideal income after m days, can get the biggest income

Assuming that the ideal income for the first day is f[i]

Then there are F[i]=max (F[j]/v[k]) *v[i]; J<=k<i

M[i]=max (F[j]/v[k]) =max (M[i-1],mf[i-1]/v[i]); M[i] Indicates the maximum number of shares that can be obtained on day I, Mf[i-1] represents the largest income that can be obtained before i-1 days

Mf[i]=max (MF (i-1), F (i-1))

13. General RMQ Problems (Range minimum/maximum Query)

  for a given n and n integers a[1...n],m and M-pair subscript (x, y) (x<=y), for each pair of subscripts (x, y) a[x...y] The lowest number of subscripts          Solution:                  The pre-processing, for each point A in the interval, a floor (LOGN) with a left end is designed with a 1 interval    & nbsp            [a,a+2^0-1], [a,a+2^1-1],..., [A, A+2^floor (LOGN)-1] in the process of solving, according to the interval length of the solution. [a,a+2^ (I+1)-1], can be through two equal-length sub-range [a,a+2^i-1] and [a+2^i,a+2^ (I+1)-1];        Method of use: A, when the overlap of the interval has no effect on the result, for example, the maximum minimum value (as described in the subject, according to the interval [a,a+2^k-1] and [b-2^k+1,b] to calculate B, when the overlap of the interval affects the results, For example, the number of statistics and so on, the [a, b] is divided into [a,a+2^k-1], [a+2^k,a+2^k+2^ (Floor (b (a+2^k) +1))-1], each time using the logarithm directly to get the dividing point. So at most, it is divided into floor (log (b-a+1)) + 1 intervals. So the time complexity of this processing is logn in the subject, all of the logarithm, are based on 2.    in the case, open an array, the row subscript represents the interval at the beginning of a, the column coordinates indicate the end of the interval B

#include "stdafx.h" #include <iostream> #include <math.h> using namespace std; Class Rmqproblem {int N; int M; int *data; int **b; Public:rmqproblem () {cin>>n>>m; data=new int[n+1]; b=ne W int*[n+1]; int Tempranknum=int (Floor (log2 (N))) +1; for (int i=1;i<=n;i++) {cin>>data[i]; b[i]=new int[tempranknum], b[i][0]=data[i];} for (int j=1;j<= tempranknum;j++) {int k=1<<j; int kk=1<< (j-1); for (int i=1;i<=n-k+1;i++) {b[i][j]=min (b[i][j-1],b[i+kk ][j-1]); }} int Tempx,tempy,tempz; for (int. i=1;i<=m;i++) {cin>>tempx>>tempy; tempz=int (Floor (log2 (TEMPY-TEMPX))); Cout<<min (b[ Tempx][tempz],b[tempy-int (1<<TEMPZ)][tempz]); }} double log2 (double x) {return log (double (x))/log (2.0);} int min (int x,int y) {return x<y?x:y;}}; 14, a dynamic programming method for the problem of splitting stones

There are n stones, K-frames. Put n stones in the order of K-frames, such as the 1,4~6 into the 2, the maximum weight of the frame requires the minimum weight of the method.

The weights of the Stones are q1,q2, respectively ...

G (i,j) =qi+,..., +qj;

F (i,j) is the weight of the maximum weight box that puts the I stone into the J box.

Then f (i,j) =minj-1<=p<i (f (i,j), Max (f (p,j-1), G (P+1,i)));

G (I,i) =qi, F (=g), F (i,1) =g (1,i);

1<=i<=n;

1<=j<=k;

If the SI =q1+,.., +qi is calculated in advance, G (j,k) =sk-sj-1 The time Complexity O (N2)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.