poj 3176 Cow Bowling

来源:互联网 发布:淘宝刷钻平台那个好 编辑:程序博客网 时间:2024/06/02 02:32

题意:非常经典的dp,就是数塔,从上往下可以向右下走,和向下走,问最后得到的和最大值。
1.先找子问题,从第n层开始,到最后一层的最大值。确定符合无后效性,和最优子结构的特点。
2.然后确立状态dp[i][j]表示从第i层第j个开始到最后
的最大值。
3.然后在确立状态转移方程,dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+D[i][j];
4.最后注意边界的处理,dp[n][j]=D[n]j.
输入
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

样例输出

30

#include<cstdio>,#include<cstring>#include<algorithm>using namespace std;int dp[400][400],D[400][400],N;int main(){    while(~scanf("%d",&N))    {        for(int i=1;i<=N;i++)            for(int j=1;j<=i;j++)              scanf("%d",&D[i][j]);        memset(dp,0,sizeof(dp));        for(int i=1;i<=N;i++) dp[N][i]=D[N][i];        for(int i=N-1;i>=1;i--)            for(int j=1;j<=i;j++)            dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+D[i][j];        printf("%d\n",dp[1][1]);    }}

只用一个一维数组存每层结果,节省点空间。

#include<cstdio>,#include<cstring>#include<algorithm>using namespace std;int dp[400],D[400][400],N;int main(){    while(~scanf("%d",&N))    {        for(int i=1;i<=N;i++)            for(int j=1;j<=i;j++)              scanf("%d",&D[i][j]);        memset(dp,0,sizeof(dp));        for(int i=1;i<=N;i++) dp[i]=D[N][i];        for(int i=N-1;i>=1;i--)            for(int j=1;j<=i;j++)            dp[j]=max(dp[j],dp[j+1])+D[i][j];        printf("%d\n",dp[1]);    }}
0 0