Seam Carving

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

Total Submission(s): 956    Accepted Submission(s): 382

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
 

题意:给一个N*M的矩阵,让你用一条线 从第1行连到第N行(每行仅仅能选一个元素),要求这条线所经过的元素之和最小。 
有下面规定——
1,若你选择了位置(i,j)的元素,那么下一行的元素你仅仅能选择(i+1。j-1)、(i+1。j)、(i+1,j+1)三个之中的一个(当然边界仅仅能选两个)。

2,若能够找到多条  路径上元素之和最小 的线,那么你要优先选择最右边的线。
3。最后从第一行開始 输出线上元素的纵坐标。



思路:就是树塔变形题嘛。在自底往上推最优值的过程中。设置数组记录前驱,最后选择最右边的线输出路径就可以。因为题目没有说清楚(可能是我英语太渣)在找线的过程中是否要优先选择最右边的元素,所以我在DP过程中选择从左到右一直更新前驱。


队友说DP难,没心情深挖。

没办法,仅仅好主修图论 + DP。 其他仅仅能辅修了o(╯□╰)o


AC代码:


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Node
{
int pos;
};
Node mark[110][110];//标记该位置是由 哪一位置得到的(自底往上)
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]);//找到最小值
dp[i][j] += t;
//从左到右更新 前驱
if(t == dp[i+1][j])
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])//优先选择最右边的线
{
Max = dp[1][i];
sx = i;
}
}
printf("Case %d\n", k++);
printf("%d", sx);
int row = 1, cul = sx;//行号 列号
while(1)
{
if(row == N) break;
cul = mark[row][cul].pos;//下一列号
printf(" %d", cul);
row++;
}
printf("\n");
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &N, &M);
getMap();
solve();
}
return 0;
}

hdoj 5092 Seam Carving 【树塔DP变形 + 路径输出】 【简单题】的更多相关文章

  1. 递推DP HDOJ 5092 Seam Carving

    题目传送门 /* 题意:从上到下,找最短路径,并输出路径 DP:类似数塔问题,上一行的三个方向更新dp,路径输出是关键 */ #include <cstdio> #include < ...

  2. hdu 5092 Seam Carving (简单数塔DP,题没读懂,,不过可以分析样例)

    题意: 给一个m*n的矩阵,每格上有一个数. 找从第1行到第m行的一条路径,使得这条路径上的数之和最小. 路径必须满足相邻两行所选的两个数的纵坐标相邻(即一个格子必须是另一个格子的周围八个格子中的一个 ...

  3. HDU 5092 Seam Carving (dp)

    题意,给一个数字矩阵,要求从上往下的一条路径,使这条路径上数字之和最小,如有多条输出最靠右的一条. 数字三角形打印路径... 一般打印路径有两种选择,一是转移的时候加以记录,二是通过检查dp值回溯. ...

  4. hdu 5092 Seam Carving

    这道题 我没看出来 他只可以往下走,我看到的 8-connected :所以今天写一下如果是 8-connected 怎么解: 其实说白了这个就是从上到下走一条线到达最后一行的距离最小: 从Map[a ...

  5. uva 10131 Is Bigger Smarter ? (简单dp 最长上升子序列变形 路径输出)

    题目链接 题意:有好多行,每行两个数字,代表大象的体重和智商,求大象体重越来越大,智商越来越低的最长序列,并输出. 思路:先排一下序,再按照最长上升子序列计算就行. 还有注意输入, 刚开始我是这样输入 ...

  6. 【DP系列学习一】简单题:kickstart2017 B.vote

    https://code.google.com/codejam/contest/6304486/dashboard#s=p1 这是一道简单的dp,dp[i][j]代表A的voter为i,B的voter ...

  7. ZOJ-1456 Minimum Transport Cost---Floyd变形+路径输出字典序最小

    题目链接: https://vjudge.net/problem/ZOJ-1456 题目大意: Spring国家有N个城市,每队城市之间也许有运输路线,也可能没有.现在有一些货物要从一个城市运到另一个 ...

  8. 【JZOJ4746】【NOIP2016提高A组模拟9.3】树塔狂想曲

    题目描述 相信大家都在长训班学过树塔问题,题目很简单求最大化一个三角形数塔从上往下走的路径和.走的规则是:(i,j)号点只能走向(i+1,j)或者(i+1,j+1).如下图是一个数塔,映射到该数塔上行 ...

  9. HDU5092——Seam Carving(动态规划+回溯)(2014上海邀请赛重现)

    Seam Carving DescriptionFish likes to take photo with his friends. Several days ago, he found that s ...

随机推荐

  1. 南海区行政审批管理系统接口规范v0.3(规划) 3.业务办理API 3.1.businessAuditById【业务办理】

    {"c_accept":"Q2015112400002","c_operators":"gz99","v_op ...

  2. hihoCoder-1839 榶榶榶 数学

    题面 题意:给你一个500000长度的数字,然后环形的让每位做头,例如123,就有123,231,312三个,然后问这n个数字的和S,S的最小非1因子是多少 题解:每个数字在每个位置都会有一次,如果说 ...

  3. c语言递归讲解分析

    C语言允许函数调用它自己,这种调用的过程称为"递归(recursion)" 举例说明,如下代码: #include <stdio.h> void up_and_down ...

  4. MYSQL工具之binlog2sql闪回操作

    文档结构: 在生产环境中如果遇到误删,改错数据的情况,利用mysql闪回工具binlog2sql,可以实现数据的快速回滚,从binlog中提取SQL,并能生成回滚SQL语句.Binlog以event作 ...

  5. LeetCode Weekly Contest 24

    1, 543. Diameter of Binary Tree 维护左右子树的高度,同时更新结果,返回以该节点结束的最大长度.递归调用. /** * Definition for a binary t ...

  6. CMD-echo

    echo 打印 <> echo ^< echo ^> echo 换行 echo 你好@echo.世界. echo 多行打印 > log.log 此时 > 无效.(我 ...

  7. ridis 集群配置

    ./redis-cli -h 192.168.106.128 -p  6379 redis 1.ping 2.set str1 abc    get str1 3.  mkdir ../redis-c ...

  8. 【Oracle】SCOPE=MEMORY|SPFILE|BOTH

    SCOPE=MEMORY|SPFILE|BOTH 指示了修改参数时的“作用域”: SCOPE=MEMORY :只在实例中修改,重启数据库后此次修改失效. SCOPE=SPFILE :只修改SPFILE ...

  9. py2exe打包OpenCV,找不到libiomp5md.dll

    问题:py2exe打包OpenCV,找不到libiomp5md.dll 解决方法:把 libiomp5md.dll 从numpy/core/ 里面复制到 python27/DLLS/文件夹!!!

  10. SDL2源代码分析

    1:初始化(SDL_Init()) SDL简介 有关SDL的简介在<最简单的视音频播放示例7:SDL2播放RGB/YUV>以及<最简单的视音频播放示例9:SDL2播放PCM>中 ...