zoukankan      html  css  js  c++  java
  • Ural_1026.Ministy (DP)

      /*昨天看这题,没思路。今天开始做这题,WA到爆了!NND, 把M和N的大小整反
    了。一遍一遍的盯着我的程序看,苍天啊!浪费生命啊!

    思路:

      转移方程:dp[i][j] = min(dp[i-1][j], dp[i][j+1], dp[i][j-1]) + a[i][j];

    然后把j从前往后,和从后往前分别走一遍。(只一遍的话实现不了转移方程)
    另外开一个数组记录到达(i, j),这个位置时过来的方向。最后顺着过来的方向,入队列,输
    出。
    我是直接从后往前推的,输出方便。
    */

    //My Code:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #define l -1
    #define r -2
    #define d 0
    using namespace std;

    const int N = 110;
    const int M = 510;

    long long dp[N][M];
    int a[N][M];
    int dir[N][M];
    int pre[M*10];

    int main() {
    //freopen("data.in", "r", stdin);

    int m, n, i, j, k, y;
    scanf("%d%d", &m, &n);

    for(i = m; i >= 1; i--)
    for(j = 1; j <= n; j++)
    scanf("%d", &a[i][j]);

    for(i = 1; i <= n; i++){
    dp[1][i] = a[1][i];
    dir[1][i] = d;
    }

    for(i = 2; i <= m; i++) {
    for(j = 1; j <= n; j++) {
    dp[i][j] = dp[i-1][j] + a[i][j];
    dir[i][j] = d;
    }
    }
    for(i = 2; i <= m; i++) {
    for(j = 1; j <= n; j++) { //从前往后一遍
    if(j == 1) {
    if(dp[i][j] > dp[i-1][j] + a[i][j]) {
    dp[i][j] = dp[i-1][j] + a[i][j];
    dir[i][j] = d;
    }
    } else {
    if(dp[i][j] > min(dp[i][j-1], dp[i-1][j]) + a[i][j]) {
    dp[i][j] = min(dp[i][j-1], dp[i-1][j]) + a[i][j];
    if(dp[i][j-1] < dp[i-1][j]) dir[i][j] = l;
    else dir[i][j] = d;
    }
    }
    }
    for(j = n; j >= 1; j--) { //从后往前再来一遍
    if(j == n) {
    if(dp[i][j] > dp[i-1][j] + a[i][j]) {
    dp[i][j] = dp[i-1][j] + a[i][j];
    dir[i][j] = d;
    }
    } else {
    if(dp[i][j] > min(dp[i][j+1], dp[i-1][j]) + a[i][j]) {
    dp[i][j] = min(dp[i][j+1], dp[i-1][j]) + a[i][j];
    if(dp[i][j+1] < dp[i-1][j]) dir[i][j] = r;
    else dir[i][j] = d;
    }
    }
    }
    }
    for(y = 1, i = 2; i <= n; i++)
    if(dp[m][i] < dp[m][y])
    y = i;

    k = 0; pre[k++] = y;    //顺着方向找对应的位置
    while(m != 1) {
    if(dir[m][y] == l) y--;
    else if(dir[m][y] == r) y++;
    else if(dir[m][y] == d) m--;
    pre[k++] = y;
    }
    for(i = 0; i < k-1; i++)
    printf("%d ", pre[i]);
    printf("%d\n", pre[i]);
    return 0;
    }
  • 相关阅读:
    oracle中 connect by prior 递归算法
    sql优化__rownum的使用【转】
    ASP.NET Core四大部件
    .net core Socket
    .NET Core 配置文件
    .NET Core IOC AOP
    Quartz.Net—MisFire
    Quartz.Net—配置化
    Quartz.Net—IJob特性
    Quartz.Net—DateBuilder
  • 原文地址:https://www.cnblogs.com/vongang/p/2241606.html
Copyright © 2011-2022 走看看