P1130 红牌(动态规划)

P1130 红牌

思路如下

这一题很像数字金字塔,我们可以正着求最小时间,当然也可以逆着求最小时间,

  1. 如果正着求:那么我们怎么求状态转移方程呢?,在这里我们假定状态转移方程为:dp[ i ][ j ] ,i 表示第i行,j表示第j列,dp[ i ][ j ] 则表示从开始点(第一个步)到(i , j)这个位置所需要的最小的时间。当j > 1 && i > 1 的时候,我们考虑(i, j)这个位置是有那个位置转换过来的显然是由(i , j - 1)、(i - 1 , j)两个点走过来的,到底是着这两个点中的哪个点呢?,在这里我们直接通过min函数进行选择就行了,至此还有一些细节需要注意,当 i 表示是最第一行的时候我们要特殊考虑这一行的点是由哪些点转化过来的。
  2. 如果我们逆着求:其实思路跟正着求解差不多,只不过是逆着求解这个问题而已,那么我们仍然做假设dp[ i ][ j ] ,i 表示第i行,j表示第j列,dp[ i ][ j ] 则表示从(i , j)这个位置到终点(最后一步)所需要的最小的时间。这里当 i > 1 && i <M && j >= 1 && j < N 的时候,我们考虑dp[ i ][ j ] 是由那个状态转移而来,我们可以先考虑(i , j)这个点是经过“下一步”操作可以变成(i , j. + 1)、(i + 1 , j + 1)这两个点,由于是逆向思考,所以dp[ i ][ j ] 这个点的最优值是从dp[ i ][j + 1] 、 dp[i + 1][j + 1] 这两个🀄️选取最小时间再加上 (i , j) 这个点所代表的时间map[ i ][ j ],即最终的状态转移方程为: dp[ i ][ j ] = min(dp[ i ][j + 1] 、 dp[i + 1][j + 1] ) + map[ i ][ j ]. 在理解了这些之后,剩下的就是细节了这个时候我们再考虑这种条件 i == M && j >= 1 && j < N ,其实思路还是一样把状态转移方程稍微改一下就行了:dp[i][j] += (min(dp[i][j + 1],dp[1][j + 1]) + map[i][j]);(自己想一下为什么这样),还剩下最后一处细节,我们应该怎么初始化 dp[][] 数组呢?,这个也自己理解一下吧!!!

题解如下(逆向思考题解)

#include<iostream>
#include<algorithm>
using namespace std;
const int Len = 2005;
int map[Len][Len];
int dp[Len][Len];

int main()
{
    //freopen("T.txt","r",stdin);
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i = 1; i <= m; i ++)		//输入数据
        for(int j = 1; j <= n; j ++)
            scanf("%d", &map[i][j]);
    for(int i = 1; i <= m; i ++)		//dp数组进行初始化
        dp[i][n] = map[i][n];
    for(int j = n - 1; j >= 1;j --)
        for(int i = 1; i <= m; i ++)
        {
            if(i != m)
            {
                dp[i][j] += (min(dp[i][j + 1],dp[i + 1][j + 1]) + map[i][j]);
            }
            else
                dp[i][j] += (min(dp[i][j + 1],dp[1][j + 1]) + map[i][j]);
            //cout<<dp[i][j]<<endl;
        }

    int ans = 1e10;					
    for(int i = 1; i <= m; i ++)		//遍历找最小值
        ans = min(ans , dp[i][1]);
    printf("%d",ans);

    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值