Ural_1119. Metro(DP)

  /*dp很明显,参见吴文虎老先生的《程序设计基础》。不过这道题卡内存,直接开
1000*1000的数组会超的。然后看到Discuss里有人说dp[2][1000]就可以,然后就按着这
个思路写。

if(diagonally[i-1][j-1])
  dp[1][j] = min (min (dp[0][j], dp[1][j-1]) + 100, dp[0][j-1] + 100*sqrt(2.0));
else
  dp[1][j] = min(dp[0][j], dp[1][j-1]) + 100;

每计算出一行将dp[0][...] = dp[1][...];
最后输出dp[1][m+1];

My Code:
*/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

const int N = 1005;
const double di = 100*sqrt(2.0);

double p[2][N];
bool diagonally[N][N];

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

int n, m, k, i, j;
while(~scanf("%d%d", &n, &m)) {
memset(diagonally, 0, sizeof(diagonally));
memset(p, 0, sizeof(p));

n++; m++;
scanf("%d", &k);
while(k--) {
scanf("%d%d", &i, &j);
diagonally[i][j] = true;
}
for(i = 1; i <= m; i++)
p[0][i] = (i-1)*100;

for(i = 2; i <= n; i++) {
p[1][1] = (i-1)*100;
for(j = 2; j <= m; j++) {
if(diagonally[i-1][j-1])
p[1][j] = min(min(p[0][j], p[1][j-1]) + 100, p[0][j-1] + di);
else
p[1][j] = min(p[0][j], p[1][j-1]) + 100;
}
for(j = 1; j <= m; j++)
p[0][j] = p[1][j];
}
printf("%d\n", int(p[1][m]+0.5));
}
return 0;
}
原文地址:https://www.cnblogs.com/vongang/p/2238070.html