您的位置:首页 > 其它

hdu 5092 Seam Carving 简单DP ”水一炮试试“大法

2015-05-20 17:51 453 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5092

非常卡读题

题目中说可以八个方向地走,完全没有提及是从上往下的

需要从样例中猜测”可能只是从上往下“,然后根据现场的过题情况决定要不要水一发试试

对于”水一炮试试“,感觉一般适用于:

1.本题的其他做法未果/很难写,其他的题目没法出

2.码的成本不会很高

3.心态上,得之我幸,失之我命

(水不过的时候,再检查一下水的姿势有没有什么不妥,如果还是不行,就要勇敢地、果断地走出过不了题的不开心~)

所以真正的题意是

只能从上往下走,8方向相邻

求权值和最小的路径 输出路径

如果有多条路径同时满足则输出最右的一条

教科书例题级别的DP

#include <cstring>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <set>

using namespace std;

const int maxn = 110;
const int INF = 0x7fffffff;

int a[maxn][maxn];
int dp[maxn][maxn];
int pre[maxn][maxn];

int main()
{
//freopen("in.txt", "r", stdin);

int T;
scanf("%d", &T);
int kase = 0;
while(T--)
{
printf("Case %d\n", ++kase);

int m, n;
scanf("%d%d", &m, &n);

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

for(int i = 1; i <= m; i++)
dp[i][0] = dp[i][n+1] = INF;

for(int j = 1; j <= n; j++)
dp[1][j] = a[1][j];

for(int i = 2; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
if(dp[i-1][j-1] < dp[i-1][j] && dp[i-1][j-1] < dp[i-1][j+1]) //必须要严格小于才选最左边
{
dp[i][j] = dp[i-1][j-1] + a[i][j];
pre[i][j] = j-1;
}
else if(dp[i-1][j] < dp[i-1][j+1])
{
dp[i][j] = dp[i-1][j] + a[i][j];
pre[i][j] = j;
}
else
{
dp[i][j] = dp[i-1][j+1] + a[i][j];
pre[i][j] = j+1;
}
}
}

int minloc = 0;
for(int i = 1; i <= n; i++)
if(dp[m][i] <= dp[m][minloc])
minloc = i;

stack<int> st;
for(int i = m; i >= 1; i--)
{
st.push(minloc);
if(i != 1)
minloc = pre[i][minloc];
}

for(int i = 0; i < m; i++)
{
printf("%d%c", st.top(), " \n"[i == m-1]);
st.pop();
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: