传奇手游风暴活动专区

  • 首页
  • 跨服动态
  • 行会战报
  • 装备图鉴
  • 2025-10-28 21:10:01

    HDU 2084 数塔(简单DP入门)

    数塔Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

    Total Submission(s): 41852 Accepted Submission(s): 24820

    Problem Description

    在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的:

    有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?

    已经告诉你了,这是个DP的题目,你能AC吗?

    Input

    输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。

    Output

    对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。

    Sample Input

    1

    5

    7

    3 8

    8 1 0

    2 7 4 4

    4 5 2 6 5

    Sample Output

    30

    Source

    2006/1/15 ACM程序设计期末考试

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2084

    分析:DP入门题,学长好像讲了DFS写法,没怎么听,下次补上!

    代码语言:javascript代码运行次数:0运行复制 1 #include

    2 int main()

    3 {

    4 int C,i,j,N;

    5 int a[101][101];

    6 while(scanf("%d",&C)==1)

    7 {

    8 while(C--)

    9 {

    10 scanf("%d",&N);

    11 for(i=0;i

    12 for(j=0;j<=i;j++)

    13 scanf("%d",&a[i][j]);

    14 for(i=N-1;i>=0;i--)

    15 {

    16 for(j=0;j<=i;j++)

    17 {

    18 if(a[i][j]+a[i-1][j]>a[i][j+1]+a[i-1][j])

    19 a[i-1][j]=a[i][j]+a[i-1][j];

    20 else

    21 a[i-1][j]=a[i][j+1]+a[i-1][j];

    22 }

    23 }

    24 printf("%d\n",a[0][0]);

    25 }

    26 }

    27 return 0;

    28 }以上这种是别人的想法,下面我来说说我对DP的理解!

    解题思路:

    用二维数组存放数字三角形。

    D( r, j) : 第r行第 j 个数字(r,j从1开始算)

    MaxSum(r, j) : 从D(r,j)到底边的各条路径中,

    最佳路径的数字之和。

    问题:求 MaxSum(1,1)

    典型的递归问题。

    D(r, j)出发,下一步只能走D(r+1,j)或者D(r+1, j+1)。故对于N行的三角形:

    if ( r == N)

    MaxSum(r,j) = D(r,j)

    else

    MaxSum( r, j) = Max{ MaxSum(r+1,j), MaxSum(r+1,j+1) } + D(r,j)

    并且每算出一个MaxSum(r,j)就保存起来,下次用

    到其值的时候直接取用,则可免去重复计算。那么

    可以用O(n 2 )时间完成计算。因为三角形的数字总

    数是 n(n+1)/2!

    下面给出我的代码:

    代码语言:javascript代码运行次数:0运行复制 1 #include

    2 using namespace std;

    3 int dp[105][105];

    4 int maxSum[105][105];

    5 int n;

    6 int MaxSum(int i,int j)

    7 {

    8 if(maxSum[i][j]!=-1)

    9 return maxSum[i][j];

    10 if(i==n)

    11 maxSum[i][j]=dp[i][j];

    12 else

    13 {

    14 int x=MaxSum(i+1,j);

    15 int y=MaxSum(i+1,j+1);

    16 maxSum[i][j]=max(x,y)+dp[i][j];

    17 }

    18 return maxSum[i][j];

    19 }

    20 int main()

    21 {

    22 int T;

    23 while(cin>>T)

    24 {

    25 while(T--)

    26 {

    27 cin>>n;

    28 for(int i=1;i<=n;i++)

    29 for(int j=1;j<=i;j++)

    30 {

    31 cin>>dp[i][j];

    32 maxSum[i][j]=-1;

    33 }

    34 cout<

    35 }

    36 }

    37 return 0;

    38 }

    十大护眼app排行 护眼软件哪个好 视力保护助手app推荐→MAIGOO生活榜
    怎样才知道手机被黑客入侵
    跨服动态

    友情链接:

    ©Copyright © 2022 传奇手游风暴活动专区 All Rights Reserved.