第一个清晰动态规划

dynamic(动态的) programing(表格法)
学动态两周了,整理一下第一个懂的规划题
学规划累了就整理,不累就听课做题,都不想干了就翻译学英语。
1163:The Triangle

	查看
	提交
			统计
			提示
		
	提问
		



	总时间限制: 
	1000ms
		内存限制: 
	65536kB


	描述
	7

3 8
8 1 0
2 7 4 4
4 5 2 6 5

(Figure 1)
Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.

			输入
	Your program is to read from standard input. The first line contains one integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100. The numbers in the triangle, all integers, are between 0 and 99. 
	输出
	Your program is to write to standard output. The highest sum is written as an integer.
	样例输入
	5

3 8
8 1 0
2 7 4 4
4 5 2 6 5
样例输出
3
首先定义数组
dp[i][j]来表示在ij位置上的最优路径的和
z注意是最优
calculates the highest sum of numbers passed on that point
找出元素之间的关系式
就是进行无后效性和最优子机构啥的绕口令
也可以说是吧大问题分成小问题 这里我有点领悟在以上两原则的基础上小问题可以看做更小问题的大问题,知道最小
另外就是要找到关键的结束问题 就像
此题到达ij位置的最优路径有从上方{i-1,j}左侧{i,j-1}两种
dp[i][j]=max{dp[i-1][j],dp[i][j-1]}+本身值
此时用于比较的两个已成为最优
找初始值
数组有问题,i=0这个0维数组可能为负,会爆炸

#include <iostream>
#include <algorithm>
#define MAX 101
using namespace std;
int D[MAX][MAX];
int n;
int MaxSum(int i, int j){
if(i==n)
return D[i][j];
int x = MaxSum(i+1,j);
int y = MaxSum(i+1,j+1);
return max(x,y)+D[i][j];
}

int main(){
int i,j;
cin >> n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin >> D[i][j];
cout << MaxSum(1,1) << endl;
4```



7
1
3 1 8 1
8 1 1 2 0 1
2 1 7 3 4 3 4 1
4 1 5 4 2 6 6 4 5 1
如果采用递规的方法,深度遍历每条路径,存在大
量重复计算。则时间复杂度为 2 n ,对于 n = 100 行,会超时
是
```bash
在这里插入代码片

中间的空格是重复执行的次数
所以

  1. L
    在该有的位置存放从下而上推来的最优最优最优数值
话不多说,干
#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 101
int main()
{
    int dp[MAX][MAX];
    int dpp[MAX][MAX];
    int i,j,n;
    cin>>n;
    for(i=1;i<=n;i++)
    {for(j=1;j<=i;j++)
        {cin>>dp[i][j];}
    }
    for(i=1;i<=n;i++)
     dpp[n][i]=dp[n][i];
    for(i=n-1;i>=1;i--)
     for(j=1;j<=i;j++)
       dpp[i][j]=max(dpp[i+1][j],dpp[i+1][j+1])+dp[i][j];
    
    cout<<dpp[1][1]<<endl;
    return 0;
}

这其中,我没用到初始值。用的数组中间的一部分数
这样想的话是不是就不用定义初始值了。我真聪明。
关于优化
这个题可以用一维数组
很使用的一道题
但是上边在poj可通过,在那个一本通就不行了,不知道为啥,就三个通过绿色
现在来搞一下

节省空间,时间复杂度不变
30
#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 101
int D[MAX][MAX];
int n; int * maxSum;
int main(){
int i,j;
cin >> n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin >> D[i][j];
maxSum = D[n]; //maxSum指向第n行
for( int i = n-1; i>= 1; --i )
for( int j = 1; j <= i; ++j )
maxSum[j] = max(maxSum[j],maxSum[j+1]) + D[i][j];
cout << maxSum[1] << endl;
}
这用了滚动数组
用五行的例子看
先从第四行找出四个最大值
于是3.2.1.。。。。。。。
收工下个星期回来写为什么只通过三个数据,现在不会。

end…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值