HIHOCODE #1241:Best Route in a Grid

来源:互联网 发布:小浪底水利枢纽知乎 编辑:程序博客网 时间:2024/06/01 07:39
时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

给定一个N行N列的非负整数方阵,从左上角(1,1)出发,只能向下或向右走,且不能到达值为0的方格,求出一条到达右下角的最佳路径。所谓最佳路径是指途经的数的乘积的末尾连续的0最少。

输入

输入文件的第一行包含一个整数N,其中1≤N≤1000。

接下来的N行每行包含N个非负整数,其中每个数小于等于1,000,000。

数据保证至少存在一条不全为0的路径。最佳路径是指途经的数的乘积的末尾连续的0最少

输出

输出文件仅一行,包含一个整数,表示要求的最佳路径上所有数字乘积的末尾连续零的个数。

样例输入
41 3 0 00 8 2 256 5 0 30 15 7 4
样例输出
2
解题思路
该题的要求是找出一条最佳途数的乘积的末尾连续的0最少的一条路径。则重点在于如何判断0最少。
可知:
        10=2*5
那么换一个角度来说,只要结果的末尾有0,那么经过的路径的元素必有2的倍数以及5的倍数(题目中已经要求不经过值为0的点)。从而,问题则可以转化为,求取一条路径,使得该路径经过的各个点的值中,存在因子2的个数或存在因子5的个数最小。
根据以上分析,我们可以将问题分为两个部分进行:
(1)求取存在因子2个数最少的一条路径
(2)求取存在因子5个数最少的一条路径
对于上述两个部分,其原理是相同的,都可以看做是动态规划的问题进行求解:
对于方阵中任意一点(i,j):
       其最短路径dp[i][j]=min(dp[i][j],min(dp[i-1][j],dp[i][j-1])+w[i][j])
根据上述的关系式,则可以完成代码的编写。
AC代码如下:
#include<iostream>#include<math.h>#include<cstring>#include<algorithm>using namespace std;int mod5(int data);int mod2(int data);int p[1010][1010]={0};int dp[1010][1010]={0};int w[1010][1010]={0}; int main(){int N;cin>>N;for(int i=1;i<=N;i++){for(int j=1;j<=N;j++){cin>>p[i][j];if (p[i][j]==0)w[i][j]=1e5;}}memset(dp,0x3f,sizeof dp);dp[1][0]=0;for(int i=1;i<=N;i++){for(int j=1;j<=N;j++){if(p[i][j]!=0){w[i][j]=mod2(p[i][j]);}dp[i][j]=min(dp[i][j],min(dp[i][j-1],dp[i-1][j])+w[i][j]);}}int ans=dp[N][N];memset(dp,0x3f,sizeof dp);dp[1][0]=0;for(int i=1;i<=N;i++){for(int j=1;j<=N;j++){if(p[i][j]!=0){w[i][j]=mod5(p[i][j]);}dp[i][j]=min(dp[i][j],min(dp[i][j-1],dp[i-1][j])+w[i][j]);}}cout<<min(dp[N][N],ans)<<endl;return 0;}int mod2(int data){int k=data;int mod2=0;while(k%2==0){mod2++;k=k/2; }return mod2;}int mod5(int data){int k=data;int mod5=0;while(k%5==0){mod5++;k=k/5; }return mod5;}

0 0
原创粉丝点击