[DP]vijos1139小胖办证

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[DP]vijos1139小胖办证相关的知识,希望对你有一定的参考价值。

题目梗概

m层楼,每层楼n个办事员,办事员只有在以下三种情况任意满足一种的情况下才会帮你办证。并且每次办事会花费一定费用

1.办事员在一楼

2. 办事员左边的人或者右边的人帮你办证了。

3.办事情员楼下的人帮你办证了。

 

思考

方程不难推dp[i][j]表示前i层前m个办事员的最小花费.

dp[i][j] 从dp[i-1][j] dp[i][j-1] dp[i][j+1]三个方程转移 需要注意的问题是第一层要特殊处理。

输出的之后递归找(数据还可以)

#include <cstdio>
#include <algorithm>
#include <cstring>

using std::max;
using std::min;

int n,m,map[105][505],dp[105][505],End,Min=(1<<30)-1;


void print(int x,int y){
    if(x==1) {
        printf("%d\n",y);
        return ;
    }
    if(dp[x-1][y]+map[x][y]==dp[x][y]) print(x-1,y);
    else if(dp[x][y-1]+map[x][y]==dp[x][y]) print(x,y-1);
    else print(x,y+1);
    printf("%d\n",y);
}

int main(){
    memset(dp,0x3f3f3f3f,sizeof(dp));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&map[i][j]); 
    for(int i=1;i<=m;i++) dp[1][i]=map[1][i];
    for(int i=2;i<=n;i++){
        for(int j=1;j<=m;j++) dp[i][j]=dp[i-1][j]+map[i][j];
        for(int j=2;j<=m;j++) dp[i][j]=min(dp[i][j],dp[i][j-1]+map[i][j]);
        for(int j=m-1;j>=1;j--) dp[i][j]=min(dp[i][j],dp[i][j+1]+map[i][j]);
    }
    for(int i=1;i<=m;i++){
        if(dp[n][i]<Min){
            Min = dp[n][i];
            End=i;
        }
    }
    //printf("%d\n",End);
    print(n,End);
    return 0;
} 

 

以上是关于[DP]vijos1139小胖办证的主要内容,如果未能解决你的问题,请参考以下文章

树形dp小胖守皇宫(vijosP1144)

JDOJ-1310: VIJOS-P1144 小胖守皇宫

vijos1144小胖守皇宫

小胖守皇宫(VIJOS P1144 )题解

VijosP1112:小胖的奇偶

cqyz oj | 训练题HB办证 P1419 | DP动态规划