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


    题意:

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

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

    这个最小值要这么求——

    这是我们从起点走到终点的路径,其中N是地图的长,M是地图的宽,Ai表示路径中第i个点的值,Aavg表示路径中所有的点的值的平均值。要求这个式子的值最小。

    我们可以将它转化为

    好了,推到这里,我们需要的数学知识就结束了(实际上以我的数学知识也只能做到这里了……)。然后dp就好了——

    Dp[i][j][k],i表示第i行,j表示第j列,k表示所有Ai的和,这个里面保存的是所有 的值。

    然后dp下去就好了.

    dp[i][j][k] = min(dp[i][j][k], dp[i-1][j][k-mp[i-1][j]]+mp[i][j]*mp[i][j], dp[i][j][k-mp[i][j-1]]+mp[i][j]*mp[i][j]);

    具体见代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <algorithm>
     5 using namespace std;
     6 const int M = 1000010;
     7 const int Mod = 100000;
     8 const int N = 33;
     9 const int NN = 1800;
    10 
    11 int t, n, m;
    12 int dp[N][N][NN], mp[N][N];
    13 int ans;
    14 
    15 int Min(int x, int y)
    16 {
    17     if(x == -1) return y;
    18     return x < y ? x : y;
    19 }
    20 
    21 void Dp()
    22 {
    23     memset(dp, -1, sizeof(dp));
    24     dp[0][0][mp[0][0]] = mp[0][0]*mp[0][0];
    25     for(int i = 0; i < n; i++)
    26     {
    27         for(int j = 0; j < m; j++)
    28         {
    29             if(i-1 >= 0)
    30             {
    31                 for(int k = mp[i][j]; k < NN; k++)
    32                 {
    33                     if(dp[i-1][j][k-mp[i][j]] != -1)
    34                     {
    35                         dp[i][j][k] = Min(dp[i][j][k], dp[i-1][j][k-mp[i][j]]+mp[i][j]*mp[i][j]);
    36                     }
    37                 }
    38             }
    39             if(j-1 >= 0)
    40             {
    41                 for(int k = mp[i][j]; k < NN; k++)
    42                 {
    43                     if(dp[i][j-1][k-mp[i][j]] != -1)
    44                     {
    45                         dp[i][j][k] = Min(dp[i][j][k], dp[i][j-1][k-mp[i][j]]+mp[i][j]*mp[i][j]);
    46                     }
    47                 }
    48             }
    49         }
    50     }
    51 }
    52 
    53 int main()
    54 {
    55     //freopen("test.in", "r", stdin);
    56     scanf("%d", &t);
    57     for(int tm = 1; tm <= t; tm++)
    58     {
    59         scanf("%d%d", &n, &m);
    60         for(int i = 0; i < n; i++)
    61         {
    62             for(int j = 0; j < m; j++) scanf("%d", &mp[i][j]);
    63         }
    64         Dp();
    65         ans = -1;
    66         for(int i = 0; i < NN; i++)
    67         {
    68             if(dp[n-1][m-1][i] != -1)
    69             {
    70                 int mid = (n+m-1)*dp[n-1][m-1][i]-i*i;
    71                 if(ans == -1) ans = mid;
    72                 else ans = ans < mid ? ans : mid;
    73             }
    74         }
    75         printf("Case #%d: %d
    ", tm, ans);
    76     }
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    华大MCU烧录流程
    使用 iperf 测试网络
    Linux的Flash测试【转】
    linux 系统 UDP 丢包问题分析思路 [转]
    [规划算法]Hybrid A *算法原理
    macos 硬盘无法正常识别
    oracle定时任务
    Redis 键(key)
    redis-benchmark性能测试
    redis安装
  • 原文地址:https://www.cnblogs.com/mypride/p/4842826.html
Copyright © 2020-2023  润新知