HDU 2571 命运

题目地址:点击打开链接

思路:简单DP,但是有很多需要注意的地方,首先DP数组不能初始化为0,因为DP保存的是这个点能取得的最大幸运值,可能为0,应该初始化为一个很小的负数,第二个就是保存值时i,j要从1开始循环,因为走的是列的倍数

错误代码:

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

int a[21][1001],dp[21][1001];
int n,m;
const int MAX = -200000000;

int dfs(int x,int y)
{
    int i,max1 = MAX;
    if(dp[x][y] != MAX)
        return dp[x][y];
    if(x+1 < n)
        max1 = dfs(x+1,y);
    if(y+1 < m && dfs(x,y+1) > max1)
    {
        max1 = dfs(x,y+1);
    }
    for(i=2; i*y<m; i++)//直接在这死循环了
    {
        if(i*y < m && dfs(x,i*y) > max1)
            max1 = dfs(x,i*y);
    }
    dp[x][y] = a[x][y] + max1;
    return dp[x][y];
}

int main()
{
    int t,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=0; i<n; i++)
        {
            for(j=0; j<m; j++)
            {
                scanf("%d",&a[i][j]);
                dp[i][j] = MAX;
            }
        }
        dp[n-1][m-1] = a[n-1][m-1];
        printf("%d\n",dfs(0,0));
    }
    return 0;
}

AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

int a[21][1001],dp[21][1001];
int n,m;
const int MAX = -200000000;

int dfs(int x,int y)
{
    int i,max1 = MAX;
    if(dp[x][y] != MAX)
        return dp[x][y];
    if(x+1 <= n)
        max1 = dfs(x+1,y);
    if(y+1 <= m && dfs(x,y+1) > max1)
    {
        max1 = dfs(x,y+1);
    }
    for(i=2; i*y<=m; i++)
    {
        if(i*y < m && dfs(x,i*y) > max1)
            max1 = dfs(x,i*y);
    }
    dp[x][y] = a[x][y] + max1;
    return dp[x][y];
}

int main()
{
    int t,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=m; j++)
            {
                scanf("%d",&a[i][j]);
                dp[i][j] = MAX;
            }
        }
        dp[n][m] = a[n][m];
        printf("%d\n",dfs(1,1));
    }
    return 0;
}
AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

int a[21][1001],dp[21][1001];
const int MAX = -200000000;

int main()
{
    int t,i,j,k,n,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=m; j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        for(i=0; i<=n; i++)//处理第一列的特殊情况,在求DP值函数里面分类讨论比较麻烦,就把特殊行和列处理一下
        {
            dp[i][0] = MAX;
        }
        for(i=0; i<=m; i++)//处理第一行的特殊情况
        {
            dp[0][i] = MAX;
        }
        dp[0][1] = 0;
        dp[1][0] = 0;//处理第一个值得特殊情况,
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=m; j++)
            {
                dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
                for(k=2; k<=m; k++)
                {
                    if(j % k == 0)
                        dp[i][j] = max(dp[i][j],dp[i][j/k]);
                }
                dp[i][j] += a[i][j];
            }
        }
        printf("%d\n",dp[n][m]);
    }
    return 0;
}



你可能感兴趣的:(HDU 2571 命运)