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. layer获取弹出frame层数据

    通常,弹出层关闭之前,需要将部分数据传入父页面.这个时候怎么办呢? 通过success获取frame层的index. 然后通过cancel事件,获取子页面数据. 拿获取高德地图坐标为例: // 显示地 ...

  2. web 单一平台登录逻辑

    单点登录逻辑token=cookie('login_token');serverToken=get(token);if(serverToken!='注销'){ set('userid_已登录token ...

  3. php对文件/目录操作的基础知识(图解)

    具体的如下图所示:

  4. Python的filter与map内置函数

    简单的记录下这两个函数的功能: list(filter(lambda x : x % 2, range(10))) 上例是返回了0-10之间的所有基数组成的列表.filter()有2个参数,第一个参数 ...

  5. javascript 公历与农历相互转换工具类

    /** * 公历[1900-1-31,2100-12-31]时间区间内的公历.农历互转 * @charset UTF-8 * @Author Jea杨(JJonline@JJonline.Cn) * ...

  6. WCF与 Web Service的区别是什么?各自的优点在哪里呢?

    这是很多.NET开发人员容易搞错的问题.面试的时候也经常遇到,初学者也很难分快速弄明白 Web service: .net技术中其实就指ASP.NET Web Service,用的时间比较长,微软其实 ...

  7. (转载) IaaS, PaaS, Saas

    如果你是一个网站站长,想要建立一个网站.不采用云服务,你所需要的投入大概是:买服务器,安装服务器软件,编写网站程序. 现在你追随潮流,采用流行的云计算,如果你采用 IaaS 服务,那么意味着你就不用自 ...

  8. 7.5.5编程实例-Bezier曲线曲面绘制

    (a)Bezier曲线                         (b) Bezier曲面 1. 绘制Bezier曲线 #include <GL/glut.h> GLfloat ct ...

  9. layui 多选下拉框 控件 样式改变原因

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. JS 输入年份,再输入月份,弹出这个月有多少天?

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...