hdu 1876 dp

来源:互联网 发布:淘宝店主白娘娘怀孕 编辑:程序博客网 时间:2024/06/03 17:12

看到网上解法太多,感觉有点乱,其实就是水dp一枚,搞清递推过程就行了;

dp【i】【j】【k】k=0表示到达(i,j)这个点最多的完全消耗能量,k1小时种数,其中(i,j)这些点不是全部点,而是到达这个点能量正好为0的点或中点;

leap【】【】用来标记这些点,在跑的过程中就只跑这些点;

递推公式为

if(dp[i][j][0]+1==dp[x][y][0]) dp[x][y][1]+=dp[i][j][1];
else if(dp[i][j][0]+1>dp[x][y][0])
{
dp[x][y][0]=dp[i][j][0]+1;
dp[x][y][1]=dp[i][j][1];
}

对中点要特判下就行;

#include<stdio.h>#include<string.h>#include<iostream>using namespace std;int max(int a,int b){    return a>b?a:b;}int min(int a,int b){    return a<b?a:b;}int n,m;int judge(int x,int y){    if(x>n||y>m) return 0;    return 1;}int main(){    int i,j,T;    int map[110][110],leap[110][110];    int dp[110][110][2];    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        for(i=1;i<=n;i++)        {            for(j=1;j<=m;j++)            scanf("%d",&map[i][j]);        }        memset(dp,0,sizeof(dp));        memset(leap,-1,sizeof(leap));        dp[1][1][0]=0;        dp[1][1][1]=1;        leap[1][1]=0;        for(i=1;i<=n;i++)        for(j=1;j<=m;j++)        {            if(map[i][j]==0) continue;            if(leap[i][j]>=0)            {                int t=map[i][j];                //printf("$$$%d\n",t);                if(n-i+m-j<t)                {                    if(dp[i][j][0]==dp[n][m][0]) dp[n][m][1]+=dp[i][j][1];                    else if(dp[i][j][0]>dp[n][m][0])                    {                        dp[n][m][0]=dp[i][j][0];                        dp[n][m][1]=dp[i][j][1];                    }                        }                else if(n-i+m-j==t)                {                    if(dp[i][j][0]+1==dp[n][m][0]) dp[n][m][1]+=dp[i][j][1];                    else if(dp[i][j][0]+1>dp[n][m][0])                    {                        dp[n][m][0]=dp[i][j][0]+1;                        dp[n][m][1]=dp[i][j][1];                    }                }                else                {                    for(int k=0;k<=t;k++)                    {                        int x=i+k;                        int y=j+t-k;                        if(!judge(x,y)) continue;                        leap[x][y]=1;                        if(dp[i][j][0]+1==dp[x][y][0]) dp[x][y][1]+=dp[i][j][1];                        else if(dp[i][j][0]+1>dp[x][y][0])                        {                            dp[x][y][0]=dp[i][j][0]+1;                            dp[x][y][1]=dp[i][j][1];                        }                    }                }            }        }        printf("%d %d\n",dp[n][m][0],dp[n][m][1]);    }    return 0;}


0 0
原创粉丝点击