Seam CarvingTime
limit:2000/1000 MS (java/others) Memory limit:65536/65536 K (java/others)
Total Submission (s): 956 Accepted Submission (s): 382
Problem Descriptionfish likes to take photo with his friends. Several days ago, he found that some pictures of him were damaged. The trouble is, there is some seams across the pictures. So he tried to repair these pictures. He scanned these pictures and stored them in his computer. He knew it is an effective-on-the-carve the seams of the images He only knew that there was optical energy in every pixel. He learns the following principle of seam carving. Here seam carving refers to delete through horizontal or vertical line of pixels across the whole image to achieve image s Caling effect. In order to maintain the characteristics of the image pixels to delete the importance of the image lines must is weakest. The importance of the pixel lines is determined in accordance with the type of scene images of different energy content. That's, the place with the + and the richer texture of the image should be retained. So the horizontal and vertical lines have the lowest energy aRe the object of inspection. By constantly deleting the low-energy line it can repair the image as the original scene.
For a original image G of M*n, where M and N is the row and column of the image respectively. Fish obtained the corresponding energy matrix A. He knew every time a seam with the lowest energy should be carved. That's, the line and the lowest sum of energy passing through the pixels along the line, which is a 8-connected path ver Tically or horizontally.
Here your task was to carve a pixel from the first row to the final row along the seam. We call such seam a vertical seam.
Inputthere several test cases. The first line of the input is a integer T, which is the number of test cases, 0<t<=30. Each case begins with integers m, n, which is the row and column of the energy matrix of an image, (0<m,n<=100) . Then on the next m line, there n integers.
Outputfor each test case, print ' Case # ' on the first line, where # was the order number of the the test case (starting with 1) . Then print the column numbers of the "The Energy Matrix" from the top to the bottom on the second line. If there is more than one such seams, just print the column number of the rightmost seam.
Sample Input
24 355 32 7517 69 7354 81 6347 5 456 651 57 49 65 50 7433 16 62 68 48 612 49 76 33 32 7823 68 62 37 69 3968 59 77 77 96 59 31 88 63 79 32 34
Sample Output
Case 1 1 2Case 23 2 1 1 2 1
Test instructions: Give a n*m matrix that allows you to connect from line 1th to Nth row (only one element per line) with a line, requiring the sum of the elements passed by the line to be minimal.
have the following provisions--
1, if you choose the location (i,j) element, then the next line of elements you can only choose (i+1,j-1), (I+1,j), (i+1,j+1) One of the three (of course, the boundary can only select two).
2, if you can find the sum of the elements on multiple paths and the smallest line, then you have to first select the rightmost line.
3, finally the ordinate of the element on the output line starts from the first line.
idea: is the tree tower deformation problem. In the process of pushing the optimal value from bottom to top, set the array record precursor, and finally select the rightmost line output path. Because the topic is not clear (may be my English is too slag) in the process of finding the line to choose the rightmost element, so I choose from left to right in the DP process to update the precursor.
Teammates say DP difficult, not in the mood to dig deep. No way, had to major in the graph + DP, the other can only be repaired O (╯-╰) o
AC Code:
#include <cstdio> #include <cstring> #include <algorithm>using namespace std;struct node{int pos;}; Node mark[110][110];//marks where the position is obtained (bottom up) int dp[110][110];int n, m;int k = 1;void Getmap () {for (int i = 1; I <= N; i++) {for (int j = 1; J <= M; j + +) scanf ("%d", &dp[i][j]); }}void solve () {int t; for (int i = N-1; I >= 1, i--) {for (int j = 1; J <= M; j + +) {if (j = = 1) { t = min (dp[i+1][j], dp[i+1][j+1]);//Find minimum value dp[i][j] + = t; Update the precursor if (t = = Dp[i+1][j]) from left to right mark[i][j].pos = j; if (t = = dp[i+1][j+1]) Mark[i][j].pos = j + 1; } else if (j = = M) {t = min (dp[i+1][j], dp[i+1][j-1]); DP[I][J] + = t; if (t = = dp[i+1][j-1]) Mark[i][j].pos = j-1; if (t = = Dp[i+1][j]) Mark[i][j].pos = j; } else {int t = min (dp[i+1][j], min (dp[i+1][j-1], dp[i+1][j+1])); DP[I][J] + = t; if (t = = dp[i+1][j-1]) Mark[i][j].pos = j-1; if (t = = Dp[i+1][j]) mark[i][j].pos= J; if (t = = dp[i+1][j+1]) Mark[i][j].pos = j+1; }}} int sx = 1; int Max = dp[1][1]; for (int i = 2; I <= M; i++) {if (max >= dp[1][i])//First select the rightmost line {max = dp[1][i]; SX = i; }} printf ("Case%d\n", k++); printf ("%d", SX); int row = 1, cul = sx;//row number column number while (1) {if (row = = N) break; Cul = mark[row][cul].pos;//Next column number printf ("%d", cul); row++; } printf ("\ n");} int main () {int t; scanf ("%d", &t); while (t--) {scanf ("%d%d", &n, &m); Getmap (); Solve (); } RETUrn 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Hdoj 5092 Seam Carving "Tree Tower DP variant + path OUTPUT" "Simple question"