hdu1876

/*
分析:
    简单DP,对每个格子,选次数最多的那个往下推。


    考虑不全面,WA了一次。


                                    2012-08-20
*/










#include"stdio.h"
#include"string.h"


int n,m;
int map[111][111];
struct A
{
	int ts;
	int ms;
}dp[111][111];


int Judge(int x,int y)
{
	if(x<0 || x>=n || y<0 || y>=m)	return 1;
	return 0;
}


int main()
{
	int T;
	int i,l;
	int t,x_n,y_n;


	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);


		for(i=0;i<n;i++)
		for(l=0;l<m;l++)
			scanf("%d",&map[i][l]);


		memset(dp,0,sizeof(dp));
		dp[0][0].ms=1;
		for(i=0;i<n;i++)
		{
			for(l=0;l<m;l++)
			{
				if(i==n-1 && l==m-1)continue;


				if(map[i][l]==0)	continue;
				if(dp[i][l].ms==0)	continue;


				t=map[i][l]+1;
				x_n=i+map[i][l];
				y_n=l;
				while(t--)
				{
					if(x_n==n-1 && y_n==m-1)	{x_n--;y_n++;continue;}
					if(Judge(x_n,y_n))			{x_n--;y_n++;continue;}


					if(dp[i][l].ts+1>dp[x_n][y_n].ts)
					{
						dp[x_n][y_n].ts=dp[i][l].ts+1;
						dp[x_n][y_n].ms=dp[i][l].ms;
					}
					else if(dp[i][l].ts+1==dp[x_n][y_n].ts)	dp[x_n][y_n].ms+=dp[i][l].ms;


					x_n--;
					y_n++;
				}


				if(i+l+map[i][l]>n+m-2)
				{
					if(dp[i][l].ts>dp[n-1][m-1].ts)
					{
						dp[n-1][m-1].ts=dp[i][l].ts;
						dp[n-1][m-1].ms=dp[i][l].ms;
					}
					else if(dp[i][l].ts==dp[n-1][m-1].ts)	dp[n-1][m-1].ms+=dp[i][l].ms;
				}
				else if(i+l+map[i][l]==n+m-2)
				{
					if(dp[i][l].ts+1>dp[n-1][m-1].ts)
					{
						dp[n-1][m-1].ts=dp[i][l].ts+1;
						dp[n-1][m-1].ms=dp[i][l].ms;
					}
					else if(dp[i][l].ts+1==dp[n-1][m-1].ts)	dp[n-1][m-1].ms+=dp[i][l].ms;
				}
			}
		}


		printf("%d %d\n",dp[n-1][m-1].ts,dp[n-1][m-1].ms);
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值