I have a tree
时间限制: 1000 ms 内存限制: 65536 kb
总通过人数: 171 总提交人数: 177
题目描述
左树 右树 傻傻分不清楚
嘿,大家一起来~
小赌 豪赌 想AC就别怕苦
所以王木木去豪赌了,游戏规则如下:
在这样一棵奇怪的树中,每次王木木把一棵弹珠放在最上面的根上,然后让弹珠自由落体,弹珠有可能往左走,也有可能往右走,每次经过一个点,得分加上这个点的价值,那么王木木最多能得多少分呢?
输入
多组数据输入
每组数据第一行为正整数n(0<n<1000),为树的深度
接下来n行,第i行有i个正整数(在int范围内),表示这个点的价值
输出
对于每组数据,输出一行,最大得分的值
输入样例
4
1
3 2
4 10 1
4 3 2 15
输出样例
19
样例解释
1
3 2
4 10 1
4 3 2 15
最优路径:1->2->1->15
得分:1+2+1+15 = 19
解析:
动态规划,数字三角形问题。
从顶点往下走,走到每个点时的最大和等于max(左上角最大和,右上角最大和)+当前点数值。最后遍历最后一行的最大和,记录真最大和即为答案。
状态转移方程:
ans[i][j] = max(ans[i-1][j-1],ans[i-1][j]) + a[i][j];
代码:
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define maxn 1007
using namespace std;
int a[maxn][maxn];
int ans[maxn][maxn];
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(a,0,sizeof(a));
memset(ans,0,sizeof(ans));
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= i;j++)
{
scanf("%d",&a[i][j]);
ans[i][j] = max(ans[i-1][j-1],ans[i-1][j]) + a[i][j];
}
}
int max_ans = 0;
for(int i = 1;i <= n;i++)
{
max_ans = max(ans[n][i],max_ans);
}
printf("%d\n",max_ans);
}
}