您的位置:首页 > 理论基础 > 计算机网络

2015合肥网络赛 HDU 5492 Find a path 动归

2015-09-29 15:53 204 查看
HDU 5492 Find a path

题意:给你一个矩阵求一个路径使得

最小。

思路:

  方法一:数据特别小,直接枚举权值和(n + m - 1) * aver,更新答案。

  方法二:用f[i][j][k]表示到达[i,j]是权值和为k时平方和的最大值,转移方程就是

      f[i][j][k] = min(f[i][j][k], min(f[i - 1][j][k - a[i][j]] + sqr(a[i][j]), f[i][j - 1][k - a[i][j]] + sqr(a[i][j])));

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define LL long long
#define MAXN 10005
#define sqr(x) (x) * (x)
using namespace std;
int n, m, s;
int a[35][35], f[35][35];
int find(int x){
//s(n + m - 1)* sigma(sqr((a[i] - aver)))
memset(f, 0, sizeof(f));
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
if (i == 1 && j == 1){
f[1][1] = sqr(s * a[1][1] - x);
continue;
}
if (i == 1){
f[i][j] = f[i][j - 1] + sqr(s * a[i][j] - x);
continue;
}
if (j == 1){
f[i][j] = f[i - 1][j] + sqr(s * a[i][j] - x);
continue;
}
f[i][j] = min(f[i - 1][j] + sqr(s * a[i][j] - x), f[i][j - 1] + sqr(s * a[i][j] - x));
}
}
return f
[m] / s;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // OPEN_FILE
int T;
scanf("%d", &T);
int cas = 1;
while (T--){
scanf("%d%d", &n, &m);
s = n + m - 1;
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
scanf("%d", &a[i][j]);
}
}
int ans = INF;
for (int i = 1; i <= 1805; i++){
ans = min(ans, find(i));
}
printf("Case #%d: %d\n", cas++, ans);
}
}


#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define LL long long
#define MAXN 10005
#define sqr(x) (x) * (x)
using namespace std;
int n, m, s;
int a[35][35], f[35][35][1805];

int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // OPEN_FILE
int T;
scanf("%d", &T);
int cas = 1;
while (T--){
scanf("%d%d", &n, &m);
s = n + m - 1;
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
scanf("%d", &a[i][j]);
}
}
memset(f, INF, sizeof(f));
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
for (int k = 0; k <= 1805; k++){
if (i == 1 && j == 1){
f[i][j][a[1][1]] = sqr(a[1][1]);
continue;
}
if (k < a[i][j]) continue;
if (i == 1){
f[i][j][k] = min(f[i][j - 1][k - a[i][j]] + sqr(a[i][j]), f[i][j][k]);
continue;
}
if (j == 1){
f[i][j][k] = min(f[i - 1][j][k - a[i][j]] + sqr(a[i][j]), f[i][j][k]);
continue;
}
f[i][j][k] = min(f[i][j][k],
min(f[i - 1][j][k - a[i][j]] + sqr(a[i][j]), f[i][j - 1][k - a[i][j]] + sqr(a[i][j])));

}
}
}
int ans = INF;
int s = n + m - 1;
for (int i = 0; i <= 1801; i++){
if (f
[m][i] == INF) continue;
ans = min(ans, s * f
[m][i] - sqr(i));
}
printf("Case #%d: %d\n", cas++, ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: