hdu2571命运(dp)

题意:输入一张n*m的地图,地图上代表着一个数字,然后开始走,向下只能移动一步,向右可以走到这个列数是当前列数的倍数或者是走一步。
好吧,我还分不清这个跟dfs什么的……
感觉这个题也不是很难的样子,脑子里就是一片浆糊。
建一张map,存入各个点的值,然后再建一张dp,初始时都是0,然后每个点都记为没有被访问过,从第一个格子开始访问,依次遍历每一个格子,对于每一个格子,都是算好,它能够到达的每一个地方,然后现有的值…

终于还是看了题解才懂,上面的想法是不对的,应该反过来想,把遍历到的每一个格子都当做终点,然后找能到达它的所有的格子中最大的那个,其实这才是dp的精髓所在,就是把当前要解决的问题当做是最终的解,或者说是把大问题原封不动地缩小。

☟AC代码

#include<iostream>
using namespace std;
#include<algorithm>
#include<string.h>

int main()
{
    int c;
    scanf("%d",&c);
    while(c--)
    {
        int n,m;//n行,m列
        scanf("%d%d",&n,&m);
        int map[25][1005];
        int dp[25][1005];

        int i,j;
        for(i=0;i<=n;i++)
            dp[i][0]=-999999;
        for(i=0;i<=m;i++)
            dp[0][i]=-999999;
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
                scanf("%d",&map[i][j]);
        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]);
                int k;
                /*for(k=2;k<=m;k++)
                {
                    if(j&k==0)
                    dp[i][j]=max(dp[i][j],dp[i][k]);
                }感觉还不是很懂*/
                for(k=2;k<=m;k++)
                {
                    if(j/k==(double)j/k)
                    dp[i][j]=max(dp[i][j],dp[i][j/k]);
                }
                dp[i][j]=dp[i][j]+map[i][j];
            }
        /*for(i=1;i<=n;i++)
        {   
            for(j=1;j<=m;j++)   
                printf("%d ",dp[i][j]);
            printf("\n"); 
        }*/
        printf("%d\n",dp[n][m]); 
    }
    return 0;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值