题解 P1130 【红牌】

逆推dp经典题目:数字三角形的折叠版

为什么这么说?
因为我们会发现:除了每一次都特判一下是否转换行号以外,剩下的思想没什么不同。

没看题目的看这里



先定义:
n,m是步骤数目,小组数目
work[i][j]表示第i个小组第j步需要的天数
f[i][j]表示当前第i个小组第j步的最优天数

首先我们先看到这个题说是要求最小天数
然后我们知道这个最小天数是由原先的两个最小天数分别加上当前小组工作天数,然后二者求最小值(因为前面的两个子状态——天数决定了后面的状态——当前最小天数)
这中间告诉我们当最下面的小组还想向下找小组,就返回最上面的小组1
所以我们得出几个推论:

  1. 因为最后不同的小组会得到不同的值,所以我们应当求出最后一步中的最小天数值(最小值跑最后一列一遍)
  2. 普通(指的是不看第三点)的dp状态转移方程就是
    \[
    f[i][j]=min(f[i-1][j-1]+work[i][j],f[i][j-1]+work[i][j])
    \]
  3. 逆着想,当i=1的时候,决定当前最小天数的是i=ni=1两个子状态,所以当i=1的时候,转移的i-1就应当变成n
    于是得出下面的递推式:
    \[
    f[i][j]=min(f[i!=1?i-1:n][j-1]+work[i][j],f[i][j-1]+work[i][j])
    \]

这样这个题的思路就做完了。



代码好说:

#include <iostream>
#include <cstdio>
#define fin cin//测试来着
#define fout cout

using namespace std;
typedef long long int lli;
const int maxn=2000,maxm=2000;
lli f[maxm+1][maxn+1],work[maxm+1][maxn+1];
//f[i][j]表示当前第i个小组第j步的最优结果
lli n,m,ans=2147483647;

inline lli max(lli a,lli b) {
    return a>=b?a:b;
}
inline lli min(lli a,lli b) {
    return a<=b?a:b;
}

int main() {
    fin>>n>>m;
    for (register int i=1; i<=m; i++) {
        for (register int j=1; j<=n; j++) {
            fin>>work[i][j];
        }
    }
    //上面是按照表读的
    for (register int i=1; i<=m; i++) {
        f[i][1]=work[i][1];
    }
    //第一步就是原先第一列的内容
    for (register int i=2; i<=n; i++) {
        //从第二步骤开始推
        for (register int j=1; j<=m; j++) {
            //j是当前到了第几个小组
            if (j==1) {
                f[j][i]=min(f[m][i-1]+work[j][i],f[j][i-1]+work[j][i]);
            }
        else {
                f[j][i]=min(f[j-1][i-1]+work[j][i],f[j][i-1]+work[j][i]);
            }
        }
    }
    for (register int i=1; i<=m; i++) {
        ans=min(ans,f[i][n]);
    }
    cout<<ans;
    return 0;
}

原文地址:https://www.cnblogs.com/jelly123/p/10503135.html

时间: 2024-08-30 14:42:58

题解 P1130 【红牌】的相关文章

P1130 红牌

P1130 红牌 某地临时居民想获得长期居住权就必须申请拿到红牌.获得红牌的过程是相当复杂 ,一共包括N个步骤.每一步骤都由政府的某个工作人员负责检查你所提交的材料是否符合条件.为了加快进程,每一步政府都派了M个工作人员来检查材料.不幸的是,并不是每一个工作人员效率都很高.尽管如此,为了体现"公开政府"的政策,政府部门把每一个工作人员的处理一个申请所花天数都对外界公开. 为了防止所有申请人都到效率高的工作人员去申请.这M*N个工作人员被分成M个小组.每一组在每一步都有一个工作人员.申请

洛谷 P1130 红牌

P1130 红牌 题目描述 某地临时居民想获得长期居住权就必须申请拿到红牌.获得红牌的过程是相当复杂 ,一共包括N个步骤.每一步骤都由政府的某个工作人员负责检查你所提交的材料是否符合条件.为了加快进程,每一步政府都派了M个工作人员来检查材料.不幸的是,并不是每一个工作人员效率都很高.尽管如此,为了体现“公开政府”的政策,政府部门把每一个工作人员的处理一个申请所花天数都对外界公开. 为了防止所有申请人都到效率高的工作人员去申请.这M*N个工作人员被分成M个小组.每一组在每一步都有一个工作人员.申请

Luogu【P1130】红牌(DP)

欧拉 本蒟蒻第一个自己想出来的DP题 请移步题目链接 调了半天.i从1到n,j从1到m. f[i][j]表示的是第i道工序在第j个小组办完所花的最短时间. 因为要用到上一个状态,而上一个状态要么是同一小组,要么是上一个小组 所以j的做法跟题目是反着的 so转移方程 f[i][j]=min(f[i-1][j],f[i-1][j==1?n:j-1]); f[i][j]+=mp[j][i]; 然后就找到完成所有工序耗时最短的组就行啦 #include<cstdio> #include<cstd

[USACO07OCT]障碍路线 &amp; yzoj P1130 拐弯 题解

题意 给出n* n 的图,A为起点,B为终点,* 为障碍,.可以行走,问最少需要拐90度的弯多少次,无法到达输出-1. 解析 思路:构造N * M * 4个点,即将原图的每个点分裂成4个点.其中点(i,j,k)表示在(i,j)时人的方向是k,然后对于两个点(i,j,k)和(i,j,kk),如果k和kk是两个旋转90度能转换的方向,就连一条边权为1的边,而对于(i,j,k)和(i+dx[ k],j+dy[k],k)连一条边权为0的边,表示从(i,j)在方向为k的情况下能向k方向走一步到达(i+dx

CodeForces 281 题解

A题: 题意:给出按照时间顺序的比赛记录,比赛记录了哪一分钟有哪位球员得到了黄牌或红牌,输出罚下的人的序列. 题解:直接按照时间读入模拟就可..注意坑在有可能一位球员罚下后又得到黄牌或红牌,这时候不应再输出这个人了. B题: 题意:给出两个摔跤选手每个动作的得分,正数为第一个人得分负数为第二个人得分,总分高者胜,若相同则“字典序”较大的获胜,再相同则最后得分的人获胜. 题解:直接模拟就可..要用long long.. C题: 题意:两个队伍篮球比赛,给出每个队伍投进的每个球距离球框的距离,现在要

洛谷 P1079 Vigen&#232;re 密码 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1079 题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为 南军所广泛使用. 在密码学中,我们称需要加密的信息为明文,用 M 表示:称加密后的信息为密文,用 C 表示:而密钥是一种

8.8联考题解

今天的T1让我怀疑我是不是在做奥赛题--这考的是什么知识点啊这个,会不会用绝对值函数? Evensgn 的债务 时间限制: 1 Sec  内存限制: 128 MB 题目描述 Evensgn 有一群好朋友,他们经常互相借钱.假如说有三个好朋友A,B,C.A 欠 B 20 元,B 欠 C 20 元,总债务规模为 20+20=40 元.Evensgn 是个追求简约的人,他觉得这样的债务太繁杂了.他认为,上面的债务可以完全等价为 A 欠C20 元,B 既不欠别人,别人也不欠他.这样总债务规模就压缩到了 

POJ 2533 - Longest Ordered Subsequence(最长上升子序列) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:http://poj.org/problem?id=2533 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK)

(leetcode题解)Pascal&#39;s Triangle

Pascal's Triangle  Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,Return [ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ] 题意实现一个杨辉三角. 这道题只要注意了边界条件应该很好实现出来,C++实现如下 vector<vector<int>> generate(int