题目描述 Description
有一个数字三角形,从最顶层出发,每一步只能向左下或右下方向走。编程求从最顶层到最底层的一条路所经过位置上的数字之和mod 100的最大值。输入描述 Input Description
第一行:n( 1≤n≤25 ),数字三角形共有n行;
以下R行:依次表示数字三角形中每行中的数字。
每个数都是非负的,且 ≤ 100.输出描述 Output Description
一个正整数,路径上数字之和 mod100 的最大值。样例输入 Sample Input
2
1
99 98样例输出 Sample Output
99题解Solution
直接用数字三角形的dp方程加上模100是不行的,因为不再满足最优子结构原则了。
正确做法:
定义f[i][j][k]表示到达第i行第j列位置能否得到k。 (0≤k≤99) .
f[i][j][k]=f[i][j][k]∨
f[i−1][j−1][(k−a[i][j]+M)modM]∨
f[i−1][j][(k−a[i][j]+M)modM];
初始值:f[1][1][a[1][1]]=true,其余均为false.
再枚举找出第n行最大的符合题意的数即可Code
#include <cstdio>
#include <algorithm>
using namespace std;
const int M = 100;
bool f[30][30][M];
int n, a[30][30];
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i) for(int j = 1; j <= i; ++j)
scanf("%d", &a[i][j]);
f[1][1][a[1][1]] = true;
for(int i = 1; i <= n; ++i) for(int j = 1; j <= i; ++j)
for(int k = 0; k < M; ++k)
f[i][j][k] = f[i][j][k] || f[i - 1][j - 1][(k - a[i][j] + M) % M] || f[i - 1][j][(k - a[i][j] + M) % M];
int ans = 0;
for(int i = 1; i <= n; ++i) for(int j = 0; j < M; ++j)
if(f[n][i][j]) ans = max(ans, j);
printf("%d", ans);
return 0;
}