您的位置:首页 > 其它

Ural 1029

2010-11-25 15:38 351 查看
题意:从大楼的一层任意一间房间开始,从大楼的的顶层任意一间房间出来。

方法:网上都说是双重DP,在Crash了N多次以后,终于在晓东的一组数据下A了。。这组数据的检查不仅让我发现了数组越界的原因(dp[M]写成了DP
..),更让我明白了什么是双重DP,我原来以为就是DP两次,现在看来与for循环嵌套一般,DP中套DP。。。

代码:

#include <iostream>
using namespace std;
int data[120][550];
int dp[120][550];
int M, N;
int dir[120][550];
int path[120 * 550];
void Input() {
cin >> M >> N;
for (int i = 1; i <= M; i++) {
for (int j = 1; j <= N; j++) {
cin >> data[i][j];
}
}
}
void DP() {
for (int i = 1; i <= M; i++) {
for (int j = 1; j <= N; j++) {
dp[i][j] = dp[i - 1][j] + data[i][j];
dir[i][j] = 0;
}
for (int j = 2; j <= N; j++)
if (dp[i][j] > dp[i][j - 1] + data[i][j]) {
dp[i][j] = dp[i][j - 1] + data[i][j];
dir[i][j] = -1;
}
for (int j = N - 1; j >= 1; j--)
if (dp[i][j] > dp[i][j + 1] + data[i][j]) {
dp[i][j] = dp[i][j + 1] + data[i][j];
dir[i][j] = 1;
}
}
//	cout << "DP" << endl;
//	for (int i = 1; i <= M; i++) {
//		for (int j = 1; j <= N; j++) {
//			cout << dp[i][j] << " ";
//		}
//		cout << endl;
//	}
}
void PrintPath() {
int curVal = dp[M][1];
int curPos = 1;
//寻找终点
for (int j = 1; j <= N; j++) {
if (dp[M][j] <= curVal && dir[M][j] == 0) {
curVal = dp[M][j];
curPos = j;
}
}
//cout << "curPos =" << curPos << " curVal = " << curVal << endl;
int pathCnt = 0;
path[pathCnt++] = curPos;
int level = M - 1;
while (level >= 1) {
path[pathCnt++] = curPos;
if (pathCnt > 110 * 550)
break;
if (curPos > N || curPos < 0 || level < 0 || level > M)
break;
if (dir[level][curPos] == -1)
curPos--;
else if (dir[level][curPos] == 1)
curPos++;
else
level--;
}

for (int i = pathCnt - 1; i >= 0; i--) {
cout << path[i];
if (i)
cout << " ";
else
cout << endl;
}
}
int main() {
Input();
DP();
PrintPath();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: