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;
}
题意:输入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;
}
相关文章推荐
- POJ-3176 Cow Bowling 数塔,简单DP
- poj 1163/3176 数字三角形【简单DP】
- poj 3176 Cow Bowling(最简单DP题)
- POJ 3176 Cow Bowling (简单DP)
- hdu(poj)-2084(3176)-数塔-简单dp
- POJ 3176 简单DP
- POJ 3176 Cow Bowling (简单DP)
- poj 3176 Cow Bowling 简单DP
- POJ 3176 简单DP
- POJ 3176-Cow Bowling/POJ 1163-The Triangle(简单DP-数塔)
- POJ 3176 简单DP
- POJ 3176 DP(简单数塔)
- POJ 3176-Cow Bowling (简单DP)
- POJ 3176 Cow Bowling (简单dp——数塔问题)
- POJ 3176 Cow Bowling (简单DP)
- POJ 3176 (DP)
- poj 2181 Jumping Cows 【简单DP】
- poj 1157 LITTLE SHOP OF FLOWERS 【简单DP】
- POJ 3616 Milking Time(简单DP)
- POJ 1163 The Triangle & POJ 3176 Cow Bowling(DP动态规划)