DP入门50题(1) ——poj3176 数塔(详细、适合新手)

来源:互联网 发布:那些软件可以赚集分宝 编辑:程序博客网 时间:2024/05/01 15:19

前天开始复习以前的烂摊子——DP,然后到今天,水了十二道题,现在回头边敲边写博客回忆一下。这是第一道题,也是一般ACMer的DP入门第一题吧 ^_^
题意:大家也都知道的,输出从数塔第一层走到最后一层路径的最大值。

思想:直接从底向上回溯就好了,比较直接,没有直接去套背包写的,适合新手看;首先把dp数组memset全为0,然后把数组最后一层a[n-1][i]的值赋给dp最后一层dp[n-1][i],从倒数第二层开始循环,先看这一层:这倒数第二层的每一个数所在DP数组的值是这个数的值加上它下边两个数中较大的那个数的值,也就是dp[n-2][j]=a[n-2][j]+max(dp[n-1][j],dp[n-2][j+1]),这也就推出公式了:

dp[i][j] = a[i][j]+max(dp[i+1][j],dp[i+1][j+1]);

AC代码如下:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;int Max(int a,int b){return a>b?a:b;}int a[500][500],dp[500][500],n;void input(){    for(int i = 0 ; i < n ; i++)        for(int j = 0 ; j <= i ; j++)            cin >> a[i][j];    memset(dp,0,sizeof(dp));    for(int i = 0 ; i < n ; i++)        dp[n-1][i] = a[n-1][i];}void solve(){    for(int i = n-2 ; i >= 0 ; i--)        for(int j = 0 ; j <= i ; j++)        {            dp[i][j] = a[i][j] + Max(dp[i+1][j],dp[i+1][j+1]);        }        cout << dp[0][0] << endl;}int main(){    #ifdef H_R        freopen("in.txt","r",stdin);    #endif // H_R    cin.tie(false);    ios::sync_with_stdio(false);    while(cin >> n)    {        input();        solve();    }    return 0;}
0 0
原创粉丝点击