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

 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])));

 

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <fstream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <deque>
 7 #include <vector>
 8 #include <queue>
 9 #include <string>
10 #include <cstring>
11 #include <map>
12 #include <stack>
13 #include <set>
14 #define eps 1e-8
15 #define INF 0x3f3f3f3f
16 #define LL long long
17 #define MAXN 10005
18 #define sqr(x) (x) * (x)
19 using namespace std;
20 int n, m, s;
21 int a[35][35], f[35][35];
22 int find(int x){
23     //s(n + m - 1)* sigma(sqr((a[i] - aver)))
24     memset(f, 0, sizeof(f));
25     for (int i = 1; i <= n; i++){
26         for (int j = 1; j <= m; j++){
27             if (i == 1 && j == 1){
28                 f[1][1] = sqr(s * a[1][1] - x);
29                 continue;
30             }
31             if (i == 1){
32                 f[i][j] = f[i][j - 1] + sqr(s * a[i][j] - x);
33                 continue;
34             }
35             if (j == 1){
36                 f[i][j] = f[i - 1][j] + sqr(s * a[i][j] - x);
37                 continue;
38             }
39             f[i][j] = min(f[i - 1][j] + sqr(s * a[i][j] - x), f[i][j - 1] + sqr(s * a[i][j] - x));
40         }
41     }
42     return f[n][m] / s;
43 }
44 int main()
45 {
46 #ifndef ONLINE_JUDGE
47     freopen("in.txt", "r", stdin);
48     //freopen("out.txt", "w", stdout);
49 #endif // OPEN_FILE
50     int T;
51     scanf("%d", &T);
52     int cas = 1;
53     while (T--){
54         scanf("%d%d", &n, &m);
55         s = n + m - 1;
56         for (int i = 1; i <= n; i++){
57             for (int j = 1; j <= m; j++){
58                 scanf("%d", &a[i][j]);
59             }
60         }
61         int ans = INF;
62         for (int i = 1; i <= 1805; i++){
63             ans = min(ans, find(i));
64         }
65         printf("Case #%d: %d\n", cas++, ans);
66     }
67 }

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <fstream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <deque>
 7 #include <vector>
 8 #include <queue>
 9 #include <string>
10 #include <cstring>
11 #include <map>
12 #include <stack>
13 #include <set>
14 #define eps 1e-8
15 #define INF 0x3f3f3f3f
16 #define LL long long
17 #define MAXN 10005
18 #define sqr(x) (x) * (x)
19 using namespace std;
20 int n, m, s;
21 int a[35][35], f[35][35][1805];
22 
23 int main()
24 {
25 #ifndef ONLINE_JUDGE
26     freopen("in.txt", "r", stdin);
27     //freopen("out.txt", "w", stdout);
28 #endif // OPEN_FILE
29     int T;
30     scanf("%d", &T);
31     int cas = 1;
32     while (T--){
33         scanf("%d%d", &n, &m);
34         s = n + m - 1;
35         for (int i = 1; i <= n; i++){
36             for (int j = 1; j <= m; j++){
37                 scanf("%d", &a[i][j]);
38             }
39         }
40         memset(f, INF, sizeof(f));
41         for (int i = 1; i <= n; i++){
42             for (int j = 1; j <= m; j++){
43                 for (int k = 0; k <= 1805; k++){
44                     if (i == 1 && j == 1){
45                         f[i][j][a[1][1]] = sqr(a[1][1]);
46                         continue;
47                     }
48                     if (k < a[i][j]) continue;
49                     if (i == 1){
50                         f[i][j][k] = min(f[i][j - 1][k - a[i][j]] + sqr(a[i][j]), f[i][j][k]);
51                         continue;
52                     }
53                     if (j == 1){
54                         f[i][j][k] = min(f[i - 1][j][k - a[i][j]] + sqr(a[i][j]), f[i][j][k]);
55                         continue;
56                     }
57                     f[i][j][k] = min(f[i][j][k],
58                         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])));
59 
60                 }
61             }
62         }
63         int ans = INF;
64         int s = n + m - 1;
65         for (int i = 0; i <= 1801; i++){
66             if (f[n][m][i] == INF) continue;
67             ans = min(ans, s * f[n][m][i] - sqr(i));
68         }
69         printf("Case #%d: %d\n", cas++, ans);
70     }
71 }

 

posted on 2015-09-29 15:53  张济  阅读(191)  评论(0编辑  收藏  举报

导航