【HDU2571】命运

5 篇文章 0 订阅
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>

using namespace std;
const int MAXN = 100;
const int MAXM = 1100;
int maze[MAXN][MAXM];
int dp[MAXN][MAXM];
int solve(int n,int m,int N,int M)
{
//向下一次只能走一格。但是如果向右走,则每次可以走一格或者走到该行的列数是当前所在列数倍数的格子
    if(dp[n][m] != -10000000)
        return dp[n][m];
    int res = maze[n][m]; //@WA Point!!! origin:
    ///下一步可以是(x+1,y),(x,y+1)或者(x,y*k)
    if( m - 1 > 0 && m <= M ) ///左
        res = solve(n,m-1,N,M)+maze[n][m];
        ///origin: res= max(res,solve(n,m-1,N,M)+maze[n][m]);
    if( n - 1 > 0 && n <= N ) ///上
        res = max(res,solve(n-1,m,N,M)+maze[n][m]);
    for(int k = m - 1 ; k > 0 && m <= M  ; k--)
    {
        if( m % k == 0 )
        {
            res = max(res,solve(n,k,N,M)+maze[n][m]);
        }
    }
    return dp[n][m] = res;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("B:\\acm\\DP1\\E.txt","r",stdin);
#endif
    int T = 0 , N = 0, M = 0;
    while(scanf("%d",&T) != EOF)
    {
        memset(maze,0,sizeof(maze));
        for(int i = 0 ; i < T ;i++)
        {
            scanf("%d%d",&N,&M);
            for(int n = 1 ; n <= N ; n++)
            {
                for(int m = 1 ; m <= M ; m++)
                {
                    scanf("%d",&maze[n][m]);
                    dp[n][m] = -10000000;
                }
            }
            solve(N,M,N,M);
            /*for(int n = 1 ; n <= N ; n++)
            {
                for(int m = 1; m <= M ; m++)
                {
                    printf("%d ",dp[n][m]);
                }
                printf("\n");
            }*/
            printf("%d\n",dp[N][M]);
        }
    }
    return 0;
}

题目中状态给的很明显啊
dp[i][j] = max
{ maze[i][j] + dp[i][k] // j % k == 0
, dp[i-1][j]+maze[i][j]
,dp[i][j-1]+maze[i][j]
}
问题很可能出现在maze[i][j]+dp[i][k]上。


update:
问题不是出在maze[i][j]+dp[i][k]上,而是出在三个取值全用了max上,res的默认值是maze[i][j],如果数据是全负的的话那就根本不加了!!!

警钟啊!!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值