您的位置:首页 > Web前端

hdu 5492 Find a path(dp+少量数学)2015 ACM/ICPC Asia Regional Hefei Online

2015-09-27 21:51 435 查看
题意:

给出一个n*m的地图,要求从左上角(0, 0)走到右下角(n-1, m-1)。

地图中每个格子中有一个值。然后根据这些值求出一个最小值。

这个最小值要这么求——

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int M = 1000010;
const int Mod = 100000;
const int N = 33;
const int NN = 1800;

int t, n, m;
int dp

[NN], mp

;
int ans;

int Min(int x, int y)
{
if(x == -1) return y;
return x < y ? x : y;
}

void Dp()
{
memset(dp, -1, sizeof(dp));
dp[0][0][mp[0][0]] = mp[0][0]*mp[0][0];
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(i-1 >= 0)
{
for(int k = mp[i][j]; k < NN; k++)
{
if(dp[i-1][j][k-mp[i][j]] != -1)
{
dp[i][j][k] = Min(dp[i][j][k], dp[i-1][j][k-mp[i][j]]+mp[i][j]*mp[i][j]);
}
}
}
if(j-1 >= 0)
{
for(int k = mp[i][j]; k < NN; k++)
{
if(dp[i][j-1][k-mp[i][j]] != -1)
{
dp[i][j][k] = Min(dp[i][j][k], dp[i][j-1][k-mp[i][j]]+mp[i][j]*mp[i][j]);
}
}
}
}
}
}

int main()
{
//freopen("test.in", "r", stdin);
scanf("%d", &t);
for(int tm = 1; tm <= t; tm++)
{
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++) scanf("%d", &mp[i][j]);
}
Dp();
ans = -1;
for(int i = 0; i < NN; i++)
{
if(dp[n-1][m-1][i] != -1)
{
int mid = (n+m-1)*dp[n-1][m-1][i]-i*i;
if(ans == -1) ans = mid;
else ans = ans < mid ? ans : mid;
}
}
printf("Case #%d: %d\n", tm, ans);
}
return 0;
}


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