您的位置:首页 > 编程语言 > C语言/C++

POJ 3176 (简单dp)

2016-08-18 09:15 429 查看
http://poj.org/problem?id=3176

题意:输入n层数字三角形,求从第一层到最后一层最大权值和。

其实用递归很简单的解决,但是数据范围是350层,递归确实可以解决,但是会超时。

很容易看出来,maxn(i,j)是第i层第j数字到底层的最大权值和,所以要求maxn(i,j)有两种选择a(i,j)+MAX(maxn(i+1,j),maxn(i+1,j+1));

很明显这个超时代码对于一些值进行了重复计算。

#include<iostream>
using namespace std;

int n,a[355][355];

int maxn(int l,int r)
{
if(l == n)
return a[l][r];
int s1 = maxn(l+1,r);
int s2 = maxn(l+1,r+1);
if(s1 > s2)
return s1+a[l][r];
return s2+a[l][r];
}

int main()
{
cin>>n;
for(int i = 1;i <= n; i++)
for(int j = 1;j <= i; j++){
cin>>a[i][j];
}

cout<<maxn(1,1)<<endl;
return 0;
}
当然可以数组表示,这样的话可以记录它是否算过。

#include<iostream>
#include<cstring>
using namespace std;

int n,a[355][355];
int b[355][355];

int maxn(int l,int r)
{
if(l == n)
return a[l][r];
if(b[l+1][r] == -1)
b[l+1][r] = maxn(l+1,r);
if(b[l+1][r+1] == -1)
b[l+1][r+1] = maxn(l+1,r+1);
if(b[l+1][r] > b[l+1][r+1])
return b[l+1][r] + a[l][r];
return b[l+1][r+1]+a[l][r];
}

int main()
{
memset(b,-1,sizeof(b));
cin>>n;
for(int i = 1;i <= n; i++)
for(int j = 1;j <= i; j++){
cin>>a[i][j];
}

cout<<maxn(1,1)<<endl;
return 0;
}
这个 a(i,j)+MAX(maxn(i+1,j),maxn(i+1,j+1))式子可以说明了其中的规律。因此甚至可以不用递归。

#include<iostream>
using namespace std;

int n,a[355][355],b[355][355];

int main()
{
cin>>n;
for(int i = 1;i <= n; i++)
for(int j = 1;j <= i; j++)
cin>>a[i][j];

for(int i = 1;i <= n; i++)
b
[i] = a
[i];

for(int i = n;i > 1; i--){
for(int j = 1;j < i; j++)
if(b[i][j] > b[i][j+1])
b[i-1][j] = b[i][j] + a[i-1][j];
else b[i-1][j] = b[i][j+1] + a[i-1][j];
}

cout<<b[1][1]<<endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp poj 算法 c++