[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;
} 
时间: 2024-08-06 00:50:21

[DP]vijos1139小胖办证的相关文章

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

Description HB要办个签证,办证处是一座 M 层的大楼,每层楼都有 N 个办公室,编号为1..N,每个办公室有一个签证员,签证需要让第 M 层的某个签证员盖章才有效.每个签证员都要满足下面三个条件之一才会给HB盖章: 这个签证员在1楼. HB的签证已经给这个签证员的正楼下(房间号相同)的签证员盖过章了. HB的签证已经给这个签证员的相邻房间(房间号相差1,楼层相同)的签证员盖过章了. 每个签证员盖章都要收取一定费用,这个费用不超过1000000000.找出费用最小的盖章路线,使签证生

树形dp小胖守皇宫(vijosP1144)

题目链接:https://vijos.org/p/1144 题解:这道题的动归稍稍有一点的复杂,因为一个节点有可能被它的子节点观察,也有可能被父节点观察: 所以我们这样表示: f[i][0](表示当前i节点放了一个看守,即他自己和所有子节点已经被控制好) f[i][1](表示当前i节点不放看守,但是他自己和所有子节点已经被控制好) f[i][2](表示当前解点不放看守,子节点已被控制好但他自己没被控制) f[i][0]=sum(min(f[son][0],f[son][1],f[son][2])

Vijos1144小胖守皇宫【树形DP】

皇宫看守 太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫.皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候看守,在不同的宫殿安排看守所需的费用不同.可是陆小凤手上的经费不足,无论如何也没法在每个宫殿都安置留守侍卫.编程任务:帮助陆小凤布置侍卫,在看守全部宫殿的前提下,使得花费的经费最少. 输入格式: 输入数据由文件名为Guard.in的文本文件提供.输入文件中数据表示一棵树,描述如下:第1行 n,表示树中

Dp状态设计与方程总结

1.不完全状态记录<1>青蛙过河问题<2>利用区间dp 2.背包类问题<1> 0-1背包,经典问题<2>无限背包,经典问题<3>判定性背包问题<4>带附属关系的背包问题<5> + -1背包问题<6>双背包求最优值<7>构造三角形问题<8>带上下界限制的背包问题(012背包) 3.线性的动态规划问题<1>积木游戏问题<2>决斗(判定性问题)<3>圆的最大

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

POJ - 3186 Treats for the Cows (区间DP)

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&

51Nod 1009 数字1的个数 | 数位DP

题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9]*2+pow(10,i-1);else dp[i][j] = dp[i-1][9]+dp[i][j-1]; 然后注意下对于每个询问统计的时候如果当前位为1需要额外加上他后面所有位数的个数,就是n%pow(10,i-1); 这样总复杂度log(n)*10 #include <bits/stdc++.

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是