算法第三章作业
1. 任选作业题“单调递增最长子序列”、“挖地雷”、“编辑距离问题”中的一题分析。
我选择“单调递增最长子序列”。
1.1 根据最优子结构性质,列出递归方程式。
递归方程:
len[i] = max {len[j] + 1 | num[i] > num[j]}, 0 <= j < i
Ac代码:
1 #include<iostream> 2 using namespace std; 3 int dp(int *nums , int n){ 4 int len[1000]; //len[i]为到数字num[i]时最大单调子序列长度 5 len[0] = 1; 6 for(int i=0;i<n;i++){ 7 len[i] = 1; 8 9 for(int j=0;j<i;j++){ 10 if(nums[j]<nums[i] && len[j]+1>len[i]){ 11 len[i] = len[j] + 1; 12 } 13 } 14 } 15 int max=1; 16 for(int i=0;i<n;i++){ 17 if(max<len[i]){ 18 max = len[i]; 19 } 20 } 21 return max; 22 23 } 24 int main(){ 25 int n,nums[1000]; 26 cin>>n; 27 for(int i=0;i<n;i++){ 28 cin>>nums[i]; 29 } 30 cout<<dp(nums,n); 31 }
1.2 给出填表法中表的维度、填表范围和填表顺序。
维度:1
填表范围:1~n
填表顺序:从左往右
1.3 分析该算法的时间和空间复杂度
2. 你对动态规划算法的理解
动态规划避免了重复调用。比如说:计算
1+1+1+1+1 =
结果是:
1+1+1+1+1 = 5;
然后我们往左边再加上一个1:
1+1+1+1+1+1 =
我们会计算 5+1 = 6;而不是再算一遍1+1+1+1+1+1。
(知乎看到的,来自quora的网友)
3. 说明结对编程情况
结对编程可以取长补短,互相督促,真不错。
例如,有拖延症的我会临近ddl才来打代码,但我的同伴可能会很早来和我讨论,这就是我提前去敲代码。也可能是反过来。