First look at the question: pass the note (a) time limit: -Ms | Memory Limit:65535KB Difficulty:5
-
-
Describe
-
Obuchi and Xiao Xuan are good friends and classmates, they always have to talk about endless topics. A quality expansion activities, the class arranged to make a M-row N-column matrix, and Obuchi and small Xuan is arranged at both ends of the matrix diagonal, so they can not directly talk. Fortunately, they can communicate by passing a note. The note to pass through many students to the other hand, Obuchi sitting in the upper left corner of the matrix, coordinates (at a), the small Xuan sits in the bottom right corner of the matrix, coordinates (M,N). From the Obuchi to the small Xuan note can only be passed down or to the right, from the small Xuan to Obuchi note can only be passed up or to the left.
In the activity, Obuchi hope to send a note to the small Xuan, at the same time hope that the small Xuan to reply to him. Every classmate in the class can help them pass, but will only help them once, that is, if the person in the Obuchi hand to the small Xuan Note when help, then in the small Xuan handed to Obuchi when will not help. Vice versa.
There is one more thing to pay attention to, the class each classmate is willing to help a high degree of good and low (note: Obuchi and small Xuan's kindness degree is not defined, input with 0), you can use a 0-1000 natural number to express, the greater the number of the more kindness. Obuchi and small Xuan hope as far as possible to find good-hearted students to help pass the note, that is, to find two ways to pass the route, so that the two path of the classmate's kindness degree and the largest. Now, please help Obuchi and Xiao Xuan to find such two paths.
-
-
Input
-
-
The first line of input N (0<n<100) represents the number of data groups to be measured.
The first line of each set of test data inputs has 2 integers m and n separated by spaces, indicating that there are m rows n columns (2<=m,n<=50) in the class.
The next M-line is a m*n matrix, and the integer of row J in the matrix indicates the kindness (not greater than 1000) of the student sitting in row J of column I. Each row is separated by a space between n integers.
-
-
Output
-
-
each set of test data outputs a total of one row, containing an integer that represents the maximum value of the sum of kindness of the student who is involved in passing the note back and forth on both paths.
-
-
Sample input
-
-
13 30 3 92 8 55 7 0
-
-
Sample output
-
-
34
-
-
Source
-
-
NOIP2008
-
-
Uploaded by
-
-
HZYQAZASDF
-
- If you are running from the upper left corner to the bottom right corner to find the maximum value believe is a tower problem (do not understand see http://blog.sina.com.cn/s/blog_65caa9780100xrq6.html First question)
-
-
only right and left
-
- dynamic transfer equation for a number of towerproblems: dp[i][j] = max (dp[i-1][j],dp[i][j-1]);
-
-
-
Now, we
- need to get back to the title, so we can understand the maximum value for two points to go from the starting point to the end of the line
.
-
-
define state: Dp[i][j][x][y] is a maximum of two points (I,j) and (x, y)
-
- Dp[i][j][x][y] = max (max (Dp[i-1][j][x-1][y], dp[i-1][j][x][y-1]), Max (Dp[i][j-1][x-1][j], dp[i][j-1][x][j-1 ]) ;//Explain the left and top two directions
-
Code:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cmath > #include <map> #include <vector> #include <queue> #include <stack>using namespace Std;const int N = 52;int dp[n][n][n][n];int a[n][n];int Main () {//Freopen ("Input.txt", "R", stdin); int T; scanf ("%d", &t); while (t--) {int n,m; scanf ("%d%d", &n,&m); for (int i=1;i<=n;i++) {for (int j=1;j<=m;j++) scanf ("%d", &a[i][j]); } memset (Dp,0,sizeof (DP)); for (int i=1;i<=n;i++) {for (int. j=1;j<=m;j++) {for (int x = 1;x<=n;x+ +) {for (int y=2;y<=m;y++) {int tmp = MAX ( Max (Dp[i-1][j][x-1][y],dp[i-1][j][x][y-1]), Max (dp[i][j-1][x-1][y],dp[i][j-1][x][y-1])); if (x<i) { Dp[i][j][x][y] =tmp + a[i][j] + a[x][y];//puts ("a"); } else {if (y>j) { Dp[i][j][x][y] = tmp + a[i][j] + a[x][y];//printf ("B:%d\n", TMP); }}//printf ("%d%d%d%d%d%d\n", i,j,x,y,a[x][y],dp[i][j][x][y]); }}}} printf ("%d\n", Dp[n][m-1][n-1][m]); } return 0;}
-
-
result: Timed out!
-
It shows that the
-
four-layer cycle does not optimize the transfer equation
-
-
-
- Dp[i][j][x][y] = max (max (Dp[i-1][j][x-1][y], dp[i-1][j][x][y-1]), Max (Dp[i][j-1][x-1][j], dp[i][j-1][x][j-1 ]) +map "I" "J" +map "x" "Y" ;
-
-
-
- Observing the transfer equation is not difficult to spot (i-1,j) (i,j-1) (x,y-1) (x-1,y) and is the same
-
- so we can set their and for k = i +j-1
-
- here
I represents the above
i
J for the above
x
-
-
-
- y1 = k-i//The ordinate of the first point
-
- y2 = ordinate of the second point of k-j//
-
-
-
-
Dp[k][i][j]=max (Max (dp[k-1][i][j],dp[k-1][i][j-1]), Max (Dp[k-1][i-1][j],dp[k-1][i-1][j-1]) +Map[i][y1]+Map[ J][y2]
-
The
-
result is a maximum of two point graphs.
-
#include <bits/stdc++.h>//Some OJ may not support the using namespace Std;int map[55][55];int dp[110][55][55];int main () {int t; scanf ("%d", &t); while (t--) {memset (map,0,sizeof (MAP)); Memset (Dp,0,sizeof (DP)); int m,n; scanf ("%d%d", &m,&n); for (int i=1;i<=m;i++) for (int j=1;j<=n;j++) scanf ("%d", &map[i][j]); int k,i,j; for (k=2;k<=m+n;k++) {for (i=1;i<=m;i++) {for (j=1;j<=m;j++) {int y1 = k-i; int y2 = k-j; if (y1>n| | y1<0| | y2>n| | y2<0) {continue; } if (y1==y2) continue; DP[K][I][J] = max (max (dp[k-1][i][j],dp[k-1][i-1][j)), Max (Dp[k-1][i][j-1],dp[k-1][i-1][j-1]) +map[i][k-i]+map[j][ K-J]; }}} printf ("%d\n", dp[m+n-1][m][m-1]); }}
-
#include <bits/stdc++.h>//<strong style= "Font-family:tahoma, Arial, Sans-serif, SimSun; Background-color:rgb (255, 255, 255); " ></strong><pre name= "code" class= "CPP" style= "Display:inline!important;" > Some OJ may not support
Using namespace Std;int dp[110][55][55];int map[55][55];int main () {int t; scanf ("%d", &t), while (t--) {int n,m; scanf ("%d%d", &m,&n); for (int i = 1;i <= m; i++) {for (int j = 1;j <= N; j + +) {scanf ("%d", &map[i][j]);}} int k,i,j; DP[2][1][1] = map[1][1]; for (k = 3;k <= m+n, k++) {for (int i = 1;i <= m, i++) {for (int j = 1; J <= m;j++) {int y1 = k-i; int y2 = k-j; if (Y1 > n| | y2 > n| | Y1 < 0| | Y2 < 0) continue; DP[K][I][J] = max (max (dp[k-1][i][j],dp[k-1][i][j-1)), Max (Dp[k-1][i-1][j],dp[k-1][i-1][j-1]) +map[i][y1]+map[j][ Y2]; }}} printf ("%d\n", Dp[n+m-1][m-1][m-1]+map[m][n]); }}
A brief talk on dual-thread DP (nyoj61 nyoj712) Classic "Pass the note" and "Treasure Quest"