这是一道动态规划的题目。
给你一个数组,要求找出这个数组不连续的数字的最大情况。
1,2,4,1,7,8,3
这是原视频图文讲解
这道题可以分为选与不选的问题。从后往前看,最后第七个数字,你可以选或者不选。opt(i)位前i个数字中符合条件的最大的结果(最优解)
选:
那么结果就是value7+opt(7-2)
不选:
那么结果就是opt(7-1)
从中找出最大的就是我们要的结果了。
整个过程的式子就是opt(i)=max(valuei+opt(i-2),opt(i-1))
而无论是选或不选,都会有在分解的过程,其中就存在了大量的重叠子问题,浪费大量时间,而使用动态规划可以将O(2^n)的时间复杂度降低为O(n)
将每一步的opt的结果先保存下来,当后面要用到的时候就可以直接调用opt了,可以节省大量时间.
C++代码:
#include <iostream>
using namespace std;
class arr_opt{
public:
int *arr;
int n;
arr_opt();
int rec_opt(int i);//递归求解法
int rec();
int dp_opt(int i);//动态规划求解法
int dp();
int max(int i,int j);//辅助函数
};
int main(){
arr_opt arr;
cout<<arr.rec()<<endl;
cout<<arr.dp()<<endl;
return 0;
}
arr_opt::arr_opt(){
n=7;
arr=new int[n]{1,2,4,1,7,8,3};
//for(int i=0;i<n;i++)
// cin>>arr[i];
}
int arr_opt::rec_opt(int i){
if(i==0)
return arr[0];
else if(i==1)
return max(arr[0],arr[1]);
else{
int A=rec_opt(i-2)+arr[i];
int B=rec_opt(i-1);
return max(A,B);
}
}
int arr_opt::rec(){
return rec_opt(6);
}
int arr_opt::max(int i,int j){
if(i>j)
return i;
return j;
}
int arr_opt::dp_opt(int i){
int *opt=new int(n);
opt[0]=arr[0];
opt[1]=max(arr[0],arr[1]);
for(int i=2;i<n;i++){
int A=opt[i-2]+arr[i];
int B=opt[i-1];
opt[i]=max(A,B);
}
return opt[n-1];
}
int arr_opt::dp(){
return dp_opt(6);
}