您的位置:首页 > 其它

poj1163 dp入门题 数塔

2015-08-05 01:24 288 查看
数塔问题:给你一个数字三角形, 形式如下:

5 //三角形行数。下面是三角形

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

找出从第一层到最后一层的一条路,使得所经过的权值之和者最大。

路径上的每一步都只能往左下或右下走。三角形的行数大于1小于等于100。

问题解决思路:用递推型的dp解题,有自底向上的”人人为我“与 自顶向下的“我为人人”。

自底向上的思路是从底部向上逐级递推求出最终结果

状态dp[i][j]表示i行j列到底层所经过的权值之和的最大值

状态转移方程为:dp[i][j]=max(dp[i+1][j],dp[i+1][j])+a[i][j];

最终输出结果即为dp[0][0]

源代码:

[code]#include<iostream>
using namespace std;
int a[105][105];
int dp[105][105];
int main(){
    int n;
    while(cin>>n){
        for(int i=0;i<n;i++)
            for(int j=0;j<=i;j++)
                cin>>a[i][j];
        for(int i=n-1;i>=0;i--)
            for(int j=0;j<=i;j++)
                if(i==n-1)
                    dp[i][j]=a[i][j];
                else
                    dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j];
        cout<<dp[0][0]<<endl;
    }
    return 0;
}


由于dp[i][j]只与dp[i+1][j]及dp[i+1][j+1]有关,在每次状态转移之后第i+1行的数据就不再需要,所以可以只用一个一维数组dp[j]表示当前行各列到底层的权值和最大的路径的权值和。进而发现可以不用再开数组,直接用二维数组a即可满足状态转移过程中对内存的需求.

状态转移方程:a[i][j]=max(a[i+1][j],a[i+1][j+1])+a[i][j];

输出a[0][0];

源代码:

[code]#include<iostream>
using namespace std;
int a[105][105];
int main(){
    int n;
    while(cin>>n){
        for(int i=0;i<n;i++)
            for(int j=0;j<=i;j++)
                cin>>a[i][j];
        for(int i=n-2;i>=0;i--)
            for(int j=0;j<=i;j++)
                a[i][j]=max(a[i+1][j],a[i+1][j+1])+a[i][j];
        cout<<a[0][0]<<endl;
    }
    return 0;
}


自顶到下的思路是从顶端向下逐步更新状态来求得最优解。

状态dp[i][j]表示从i行j列到底层的最优解;

状态转移方程:dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+a[i][j];

最后的结果为底层数字的最大值。

优化好空间后的源代码:

[code]#include<iostream>
#include<algorithm>
using namespace std;
int a[105][105];
int main(){
    int n;
    while(cin>>n){
        for(int i=1;i<=n;i++)
            for(int j=1;j<=i;j++)
                cin>>a[i][j];
        for(int i=2;i<=n;i++)
            for(int j=0;j<i;j++)
                a[i][j]=max(a[i-1][j],a[i-1][j-1])+a[i][j];
        cout<<*max_element(a
,a
+n+1)<<endl;//求数组中的最大值
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: