uva 10913 Walking on a Grid

本文介绍了一个使用动态规划解决特定路径寻找问题的例子。该问题要求在一个N×N的方格中,从左上角走到右下角,使得路径上的格子数值之和最大,但同时限制了最多可以通过的负权值格子的数量。通过定义一个四维的状态来表示当前位置、剩余可走的负权值格子数量以及下一步的方向,从而解决了这一问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:有一个大小有N(最多75)的方格,要你从(1,1)走到(n,n)。

有如下规则:你只有三个方向,左、右、下。不能走出方格。一个方格只能走一次。你要保证你的路径上的格子的和最大。你最多只能走k(最多为5)个负权值的格子,从起点到终点。

要注意,因为可以向右走,所以定义三维状态可能有问题,所以定义了四维,表示从当前点向左右下走能得到的最大的值。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define LL long long
#define INF -((LL)1<<60)
const int N=80;
LL data[N][N],map[N][N][7][3];
bool vis[N][N][7][3],grid[N][N];
int n,dir[3][2]={{0,1},{1,0},{0,-1}};
bool check(int,int);
LL dp(int,int,int,int);
int main()
{
    int k,t_cnt=0;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        if(n==0&&k==0) break;
        memset(vis,0,sizeof(vis));
        memset(grid,0,sizeof(grid));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++) scanf("%lld",&data[i][j]);
        }
        if(data[n][n]<0) k--;
        LL res=dp(1,1,k+1,1);
        printf("Case %d: ",++t_cnt);
        if(res!=INF) printf("%lld\n",res);
        else puts("impossible");
    }
    return 0;
}
LL dp(int x,int y,int z,int r)
{

    bool &flag=vis[x][y][z][r];
    LL &res=map[x][y][z][r];
    if(flag) return res;
    else if((x==n&&y==n)||z==0)
    {
        flag=1;
        if(z==0) res=INF;
        else res=data[x][y];
        return res;
    }
    else
    {
        res=INF;
        for(int i=0;i<3;i++)
        {
            int xx=x+dir[i][0],yy=y+dir[i][1],t=0;
            if(data[x][y]<0) t=-1;
            if(check(xx,yy)&&!grid[xx][yy])
            {
                if((r==0&&i==2)||(r==2&&i==0)) continue;
                grid[xx][yy]=1;
                LL temp=dp(xx,yy,z+t,i);
                if(temp!=INF) res=max(res,temp+data[x][y]);
                grid[xx][yy]=0;
            }
        }
        flag=1;return res;
    }
}
bool check(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=n;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值