首页 > 代码库 > HDU 5492 Find a path (dp)

HDU 5492 Find a path (dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5492

每个数字只能走下或者走右,问你方差最小多少?

方差 = (n + m - 1) * sum(a[i]^2) + sum(a[i])

我们可以定义dp[i][j][k]为(i, j)点和为k的最小平方和,k最大也就(n-m+1)*30大小

那么可以dp[i][j][k - a[i][j]] = min(dp[i][j - 1][k], dp[i - 1][j][k]) + a[i][j]*a[i][j];

保证转移最优的话,那么需要初始化dp[i][j][k] = inf;

 1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <ctime>10 #include <list>11 #include <set>12 #include <map>13 using namespace std;14 typedef long long LL;15 typedef pair <int, int> P;16 const int N = 1e5 + 5;17 int dp[35][35][1805], a[35][35], inf = 1e6;18 19 int main()20 {21     int t, n, m;22     scanf("%d", &t);23     for(int ca = 1; ca <= t; ++ca) {24         scanf("%d %d", &n, &m);25         for(int i = 1; i <= n; ++i) {26             for(int j = 1; j <= m; ++j) {27                 scanf("%d", &a[i][j]);28                 for(int k = 0; k <= 1800; ++k) {29                     dp[i][j][k] = inf;30                 }31             }32         }33         int sum = 0;34         for(int i = 1; i <= n; ++i) {35             sum += a[i][1];36             dp[i][1][sum] = dp[i - 1][1][sum - a[i][1]] + a[i][1]*a[i][1];37         }38         sum = 0;39         for(int i = 1; i <= m; ++i) {40             sum += a[1][i];41             dp[1][i][sum] = dp[1][i - 1][sum - a[1][i]] + a[1][i]*a[1][i];42         }43         for(int i = 2; i <= n; ++i) {44             for(int j = 2; j <= m; ++j) {45                 for(int k = a[i][j]; k <= 1800; ++k) {46                     dp[i][j][k] = min(dp[i - 1][j][k - a[i][j]], dp[i][j - 1][k - a[i][j]]) + a[i][j]*a[i][j];47                 }48             }49         }50         int ans = inf;51         for(int k = 0; k <= 1800; ++k) {52             if(dp[n][m][k] < inf) {53                 ans = min(ans, dp[n][m][k] * (n + m - 1) - k*k);54             }55         }56         printf("Case #%d: %d\n", ca, ans);57     }58     return 0;59 }

 

HDU 5492 Find a path (dp)