HDU 5092 Seam Carving 递推

Seam Carving

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1353    Accepted Submission(s): 532


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
 

Source
 

Recommend
hujie

 

也是一道非常简单的递归题,注意要最右面的答案就可以了,我单独设置了一个数组存路径,其实直接回推也是可以的


#include <bits/stdc++.h>

using namespace std;

int main()
{
    int T,m,n,a[105][105],sum[105][105],ans[105][105],num,wei,hah[105],cur;
    cin>>T;
    for(int k=1;k<=T;k++)
    {
        cin>>m>>n;
        memset(sum,0x3f3f3f,sizeof(sum));
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
                cin>>a[i][j];
        for(int i=1;i<=n;i++)
        {
            sum[1][i]=a[1][i];
            ans[i][1]=1;
        }
        for(int i=2;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(sum[i-1][j+1]<=sum[i-1][j-1]&&sum[i-1][j+1]<=sum[i-1][j])
                {
                    sum[i][j]=sum[i-1][j+1]+a[i][j];
                    ans[i][j]=j+1;
                }
                else if(sum[i-1][j]<=sum[i-1][j+1]&&sum[i-1][j]<=sum[i-1][j-1])
                {
                    sum[i][j]=sum[i-1][j]+a[i][j];
                    ans[i][j]=j;
                }
                else
                {
                    sum[i][j]=sum[i-1][j-1]+a[i][j];
                    ans[i][j]=j-1;
                }
            }
        }
        num=0x3f3f3f;
        for(int i=n;i>=1;i--)
        {
            if(sum[m][i]<num)
            {
                num=sum[m][i];
                wei=i;
            }
        }
        //cout<<num<<endl;
        cout<<"Case "<<k<<endl;
        cur=0;
        for(int i=m;i>=1;i--)
        {
            hah[cur++]=wei;
            wei=ans[i][wei];
        }
        for(int i=cur-1;i>0;i--)
            cout<<hah[i]<<" ";
        cout<<hah[0]<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值