• HDU5092——DP+递归输出——Seam Carving


    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
     

    大意:每行选一个,列与列之间距离不能超过1,输出从上到下连起来而且字典序最大的路径,字典序最大只要倒一下,学到了递归输出逆序方法

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 110;
    int dp[maxn][maxn];
    int path[maxn][maxn];
    int a[maxn][maxn];
    int n,m;
    const int inf = 0x3f3f3f3f;
    void print(int x,int y)
    {
        if(x == 1){
            printf("%d",y);
            return ;
        }
        print(x-1,path[x][y]);
        printf(" %d", y);
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        for(int cas = 1; cas <= T; cas++){
            memset(path,0,sizeof(path));
            memset(dp,0,sizeof(dp));
            scanf("%d%d",&n,&m);
            for(int i = 1 ; i <= n ; i++){
                for(int j = 1; j <= m ;j++){
                    dp[i][j] = inf;
                    scanf("%d",&a[i][j]);
                }
            }
            for(int i = 1; i <= m ;i++)
                dp[1][i] = a[1][i];
            for(int i = 2; i <= n ; i++){
                for(int j = m; j >= 1 ; j--){
                    for(int k = j+1; k >= j-1; k--){
                        if(k >= 1 && k <= m){
                            if(dp[i][j] > dp[i-1][k] + a[i][j]){
                                dp[i][j] = dp[i-1][k] + a[i][j];
                                path[i][j] = k;
                            }
                        }
                    }
                }
            }
            int min1 = inf;
            int vis;
            for(int i = m; i >= 1 ;i--){
                if(dp[n][i] < min1){
                    vis = i;
                    min1 = dp[n][i];
                }
            }
            printf("Case %d
    ",cas);
            print(n,vis);
            printf("
    ");
        }
        return 0;
    }
    

      

     
  • 相关阅读:
    微信开发(5):公众号消息与事件推送处理(转)
    微信开发(4):微信第三方开放平台的搭建(转)
    微信开发(3):微信公众号发现金红包功能开发,利用第三方SDK实现(转)
    微信开发(2):微信js sdk分享朋友圈,朋友,获取config接口注入权限验证(转)
    微信开发(1) :网页授权获取用户的基本信息 实现微信登录(转)
    java实现创建临时文件然后在程序退出时自动删除文件(转)
    Linux定时对日志批量打包Shell脚本及定时任务crontab 详细用法
    httpd2.4出现AH00025: configuration error
    apache启动失败
    软件工程中的反面模式(anti-pattern)
  • 原文地址:https://www.cnblogs.com/zero-begin/p/4512338.html
Copyright © 2020-2023  润新知