您的位置:首页 > 其它

hdu 5092 Seam Carving(DP+记录路径)

2014-11-04 13:32 375 查看


Seam Carving

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 119 Accepted Submission(s): 69



Problem Description

Fish likes to take photo with his friends. Several days ago, he found that some pictures of him were damaged. The trouble is that there are 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 way to carve the seams of the images He only knew that there is 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 scaling effect. In order to maintain the characteristics of the image pixels to delete the importance of the image lines must be weakest. The importance of the pixel lines is determined in accordance with the
type of scene images of different energy content. That is, the place with the more energy and the richer texture of the image should be retained. So the horizontal and vertical lines having 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 an original image G of m*n, where m and n are 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 is, the line with the lowest sum of energy
passing through the pixels along the line, which is a 8-connected path vertically or horizontally.

Here your task is to carve a pixel from the first row to the final row along the seam. We call such seam a vertical seam.

Input

There several test cases. The first line of the input is an integer T, which is the number of test cases, 0<T<=30. Each case begins with two integers m, n, which are the row and column of the energy matrix of an image, (0<m,n<=100). Then on the next m line,
there n integers.

Output

For each test case, print “Case #” on the first line, where # is the order number of the test case (starting with 1). Then print the column numbers of the energy matrix from the top to the bottom on the second line. If there are more than one such seams, just
print the column number of the rightmost seam.

Sample Input

2
4 3
55 32 75
17 69 73
54 81 63
47 5 45
6 6
51 57 49 65 50 74
33 16 62 68 48 61
2 49 76 33 32 78
23 68 62 37 69 39
68 59 77 77 96 59
31 88 63 79 32 34


Sample Output

Case 1
2 1 1 2
Case 2
3 2 1 1 2 1


题意:给一个m*n的矩阵,找到一个纵向的"线"使得线上的和最小并输出这条线,线能向8个方向

延伸,要求找的是纵向的一条线(每一行各取一个点连成一线) ,输出路径,若有多条路径,输出最

靠右的。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 110;

int dp[maxn][maxn],path[maxn][maxn],a[maxn][maxn],n,m;

void initial()
{
memset(path,-1,sizeof(path));
for(int i=0; i<maxn; i++)
for(int j=0; j<maxn; j++)
dp[i][j]=inf;
}

void input()
{
scanf("%d %d",&n,&m);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
scanf("%d",&a[i][j]);
}

void print(int num,int index)
{
if(num<1)  return ;
if(path[num][index]==-1)
{
printf("%d ",index);
return ;
}
else
{
print(num-1,path[num][index]);
printf("%d ",index);
}
}

void solve(int co)
{
printf("Case %d\n",co);
for(int j=1; j<=m; j++)  dp[1][j]=a[1][j];
for(int i=2; i<=n; i++)
for(int j=1; j<=m; j++)
{
if(j!=1 && dp[i][j]>dp[i-1][j-1]+a[i][j])
{
dp[i][j]=dp[i-1][j-1]+a[i][j];
path[i][j]=j-1;
}
if(dp[i][j]>=dp[i-1][j]+a[i][j])
{
dp[i][j]=dp[i-1][j]+a[i][j];
path[i][j]=j;
}
if(j!=m && dp[i][j]>=dp[i-1][j+1]+a[i][j])
{
dp[i][j]=dp[i-1][j+1]+a[i][j];
path[i][j]=j+1;
}
}
int Min=inf,index=-1;
for(int j=m;j>=1;j--)
{
if(Min>dp
[j])
{
Min=dp
[j];
index=j;
}
}
print(n-1,path
[index]);
printf("%d\n",index);
}

int main()
{
int T;
scanf("%d",&T);
for(int co=1; co<=T; co++)
{
initial();
input();
solve(co);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: