算法第三章作业
动态规划算法的理解:
一、含义
动态规划:多阶段(两段)最优化决策解决问题的过程就称为动态规划。
二、基本步骤
1、描述优解的结构特征。
2、递归地定义一个最优解的值。
3、自底向上计算一个最优解的值。
4、从已计算的信息中构造一个最优解。
三、何时采用动态规划
(1) 最优化原理:问题的最优解包含的字问题也有最优解,就称该问题具有最优子结构,满足最优化原理。
(2)有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(处理重叠子问题是动态规划的优势所在)
四、例题
(1)
题目:
思路:很明显要用dp来做。我们以dp[ ]数组(假设现在是dp[ x ])记录此时以 x 为结尾的最长单调递增子序列的长度,a[ ]数组记录初始数据。
则可以得到状态转移方程 :
1 for(int i=1;i<n;i++){ 2 for(int j=0;j<i;j++){ 3 if(a[i]>a[j]&&dp[i]<dp[j]+1){ 4 dp[i]=dp[j]+1; 5 } 6 }
AC代码:
1 #include<iostream> 2 using namespace std; 3 int n,max,temp,cnt; 4 int dp[1050],a[1050]; 5 int find(){ 6 int temp=0; 7 for(int i=1;i<n;i++){ 8 for(int j=0;j<i;j++){ 9 if(a[i]>a[j]&&dp[i]<dp[j]+1){ 10 dp[i]=dp[j]+1; 11 } 12 } 13 temp=temp>dp[i]?temp:dp[i]; 14 } 15 return temp; 16 } 17 int main(){ 18 cin>>n; 19 fill(dp,dp+n,1); 20 for(int i=0;i<n;i++) cin>>a[i]; 21 int max=find(); 22 cout<<max<<endl; 23 return 0; 24 }
(2)
题目:
思路:明显的dp题,当然最短路径也可以做。(把花费看成距离)。设dp[ i ][ j ]是从 i 到 j 的最近距离,当我们没开始求解的时候它是初始距离,dp【1】【n】即为起点到终点的距离。
我们考虑最后一步到达终点的状态,dp【1】【n】=min(dp【1】【n-1】+dp【n-1】【n】,dp【1】【n】);这样我们就得出了我们的状态转移方程:
1 void DP(){ 2 for(int len=2;len<=n;len++){ 3 for(int i=1;i<=n-len+1;i++){ 4 int ed=i+len-1; 5 for(int j=i+1;j<ed;j++){ 6 if(dp[i][ed]>dp[i][j]+dp[j][ed]) 7 dp[i][ed]=dp[i][j]+dp[j][ed]; 8 } 9 } 10 } 11 }
AC代码:
1 #include<iostream> 2 using namespace std; 3 typedef long long ll; 4 int n; 5 int dp[250][250]; 6 void DP(){ 7 for(int len=2;len<=n;len++){ 8 for(int i=1;i<=n-len+1;i++){ 9 int ed=i+len-1; 10 for(int j=i+1;j<ed;j++){ 11 if(dp[i][ed]>dp[i][j]+dp[j][ed]) 12 dp[i][ed]=dp[i][j]+dp[j][ed]; 13 } 14 } 15 } 16 } 17 int main(){ 18 cin>>n; 19 for(int i=0;i<=n;i++) 20 for(int j=0;j<=n;j++) 21 dp[i][j]=0; 22 for(int i=1;i<=n;i++) 23 for(int j=i+1;j<=n;j++) 24 cin>>dp[i][j]; 25 DP(); 26 cout<<dp[1][n]<<'\n'; 27 return 0; 28 }
结对编程情况:
配合越来越默契,队友(vgen)也真的非常厉害,一起基本上能解决书本上的问题。互相学习互相帮助,期待下一次结对编程。