zoukankan      html  css  js  c++  java
  • hdu1876(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1876

    题意:问机器人到达终点的过程中最多有几次完全消耗完能量,消耗完这么多次能量的方式有几种。

    分析:模拟一下可知,每次走到下一次消耗完时必定在一条对角线上。

    以sample为例:

    image

    由于整个过程是以对角线的方向递推下去的,每次必定是往右下方走的,所以只需按着正常循环递推即可,当然按对角线右下方循环也可,不过那样略微麻烦。dp[i][j].num表示走到点(i,j)时消最多次耗完能量的次数,dp[i][j].cnt表示走到点(i,j)时消最多次耗完能量的方式。

    状态转移方程为:

                       if(dp[x][y].num<dp[i][j].num+1)
                        {
                            dp[x][y].num=dp[i][j].num+1;
                            dp[x][y].cnt=dp[i][j].cnt;
                        }
                        else if(dp[x][y].num==dp[i][j].num+1)
                            dp[x][y].cnt+=dp[i][j].cnt;

    本题还有好几个坑,能量为0的格子不能走,在终点时就不用递推了,样例没有刚好在终点时消耗完能量,所以这里被坑得好惨T^^T

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define N 10010
    using namespace std;
    struct node
    {
        int cnt,num;
    } dp[110][110];
    int flag[110][110],a[110][110];
    int main()
    {
        int t,n,m,x,y;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++)
                for(int j=1; j<=m; j++)scanf("%d",&a[i][j]);
            memset(flag,0,sizeof(flag));
            memset(dp,0,sizeof(dp));
            flag[1][1]=1;
            dp[1][1].cnt=1;
            for(int i=1; i<=n; i++)
                for(int j=1; j<=m; j++)
                {
                    if(i==n&&j==m)continue;//这里尤为注意
                    if(flag[i][j])
                    {
                        if(!a[i][j])continue;//能量为0时不能走
                        x=i+a[i][j];
                        y=j;
                        int t=a[i][j]+1;
                        if(x+y<=m+n)
                        {
                            while(t--)
                            {
                                if(x>n||y>m||x<=0||y<=0)//不在方格内不算
                                {
                                    x--;
                                    y++;
                                    continue;
                                }
                                flag[x][y]=1;
                                if(dp[x][y].num<dp[i][j].num+1)//取次数多的
                                {
                                    dp[x][y].num=dp[i][j].num+1;
                                    dp[x][y].cnt=dp[i][j].cnt;
                                }
                                else if(dp[x][y].num==dp[i][j].num+1)
                                    dp[x][y].cnt+=dp[i][j].cnt;
                                x--;
                                y++;
                            }
                        }
                        else//走到终点没消耗完能量的
                        {
                            if(dp[n][m].num<dp[i][j].num)
                            {
                                dp[n][m].num=dp[i][j].num;
                                dp[n][m].cnt=dp[i][j].cnt;
                            }
                            else if(dp[n][m].num==dp[i][j].num)
                                dp[n][m].cnt+=dp[i][j].cnt;
                        }
                    }
                }
            printf("%d %d
    ",dp[n][m].num,dp[n][m].cnt);
        }
    }
    View Code
  • 相关阅读:
    C#调用C++ memcpy实现各种参数类型的内存拷贝 VS marshal.copy的实现 效率对比
    UGUI 事件穿透规则
    UGUI 锚点设置为四方扩充模式然后设置局部坐标为0将出现什么问题
    UNITY polygon collider不随物体旋转
    android Handler机制 消息机制
    java final finally finalize
    collection 和 collections
    java 不通过第三个字符串,实现一个字符串倒序
    ArrayList,Vector,LinkedList
    String StringBuffer stringbuilder 区别
  • 原文地址:https://www.cnblogs.com/lienus/p/4154400.html
Copyright © 2011-2022 走看看