Time Limit:1000MSMemory Limit:65536KB
Total Submit:138Accepted:67
Description
有一个由正整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数,如下图所示.
1
3 2
4 10 1
4 3 2 20
从第一行的数开始,每次都只能左下或右下走一格,直到走到最下行,把沿途经过的数全部乘起来.如何走,使得个位数的积尽量大?
Input
输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。
Output
对于每个测试实例,输出可能得到的最大个位数。
Sample Input
1
4
1
3 2
4 10 1
4 3 2 20
Sample Output
8
Source
题目:EOJ1825
题目分析:思路同1824。同简单数塔相比,只需保存到此节点路径积所有可能的个位数。用dp[i][j][k]=true表示i行j列路径积个位数可为k,dp[i][j][k]=false表示i行j列路径积个位数不可能为k,最后遍历dp[1][1]的最后一维便可得出最后答案.
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int map[105][105]={};
bool dp[105][105][10];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,i,j,k;
cin>>n;
memset(map,0,sizeof(map));
memset(dp,false,sizeof(dp));
for(i=1;i<=n;++i)
{
for(j=1;j<=i;++j)
{
scanf("%d",&map[i][j]);
}
}
for(i=1;i<=n;++i)
{
dp[n][i][map[n][i]%10]=true;
}
for(i=n-1;i>0;--i)
{
for(j=1;j<=n;++j)
{
for(k=0;k<10;++k)
{
if(dp[i+1][j][k] ||dp[i+1][j+1][k])
dp[i][j][(k*map[i][j])%10]=true;
}
}
}
for(i=9;i>=0;--i)
if(dp[1][1][i])
{
printf("%d\n",i);
break;
}
}
return 0;
}