zoukankan      html  css  js  c++  java
  • POJ1163(简单的DP)

    题目链接:http://poj.org/problem?id=1163

    Description

    7
    3 8
    8 1 0
    2 7 4 4
    4 5 2 6 5

    (Figure 1)
    Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.

    Input

    Your program is to read from standard input. The first line contains one integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100. The numbers in the triangle, all integers, are between 0 and 99.

    Output

    Your program is to write to standard output. The highest sum is written as an integer.

    Sample Input

    5
    7
    3 8
    8 1 0 
    2 7 4 4
    4 5 2 6 5

    Sample Output

    30
    题意:在上面的数字三角形中寻找一条从顶部到底边的路径,使得 路径上所经过的数字之和最大。路径上的每一步都只能往左下或 右下走。只需要求出这个最大和即可,不必给出具体路径。三角形的行数大于1小于等于100,数字为 0 - 99
    解题思路:我们可以用二维数组存放数字三角形。map( i, j)   : 第i行第 j 个数字(i,j从1开始算).它是一个典型的递归问题。 map(i, j)出发,下一步只能走map(i+1,j)或者map(i+1, j+1)。但是如果采用递规的方法,深度遍历每条路径,存在大 量重复计算。则时间复杂度为 2^n,对于 n = 100 行,肯定超时。这里我们可以采用两种方法,第一种是采用记忆搜索的方法,如果每算出一个数组就保存起来,下次用 到其值的时候直接取用,则可免去重复计算。第二种是我们可以从下往上看,因为从顶边到底边的路径是和从底边到顶边的路径是一样的。我们把从第n行到第i行第j列位置的最大数字和设为dp[i][j],它肯定是底层到第i+1行的第j列的数字和即dp[i+1][j]或者到第i+1行第j+1列的数字和即dp[i+1][j+1]加上一个map[i][j]得得到的,根据动态规划的思想,我们应该去两者中更大的那个解即最优解,于是我们就能得到递推公式(即状态转移方程):dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+map[i][j],这样我们通过从最底层一步一步向上递推就很简单了,而我们要求的答案也正是最顶层的最优解即dp[1][1].
    初学DP,如有不正确的地方,望指正,谢谢。
    附上代码:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<string.h>
     4 using namespace std;
     5 int n;
     6 int map[105][105];
     7 int dp[105][105];
     8 
     9 int main()
    10 {
    11     cin>>n;
    12     for(int i=1;i<=n;i++){
    13         for(int j=1;j<=i;j++){
    14             cin>>map[i][j];
    15         }
    16     }
    17     memset(dp,0,sizeof(dp));
    18     for(int i=n;i>0;i--)
    19     {
    20         for(int j=1;j<=i;j++)
    21         {
    22             dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+map[i][j];
    23         }
    24     }
    25     cout<<dp[1][1]<<endl;
    26     return 0;
    27 }
  • 相关阅读:
    1269 匈牙利游戏 2012年CCC加拿大高中生信息学奥赛
    2577 医院设置
    2488 绿豆蛙的归宿
    3315 时空跳跃者的魔法
    1079 回家
    1365 浴火银河星际跳跃
    1074 食物链 2001年NOI全国竞赛
    2596 售货员的难题
    wetask.cn领度任务全新试用体验
    多线程--生产者消费者--简单例子
  • 原文地址:https://www.cnblogs.com/zjl192628928/p/9321022.html
Copyright © 2011-2022 走看看