在进行递归的过程中 往往会出现重复计算,而这个过程会比较浪费时间,往往会浪费掉2^n的时间复杂度,为了避免重复的计算,可以采用保留中间结果的方式来使时间复杂度降低到n方。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=10010;
// 求最长上升子序列
// 从所有的以ak结尾的最长上升子序列中找最大的那个
// a1的最长上升子序列 长度为1
// 以ak结尾的最长上升子序列
int main(){
int n;
cin>>n;
int a[maxn];
int maxLen[maxn];
for(int i=1;i<=n;i++){
cin>>a[i];
maxLen[i]=1;
}
for(int k=2;k<=n;k++){
for(int i=1;i<k;i++){
if(a[i]<a[k]){
maxLen[k]=max(maxLen[k],maxLen[i]+1);
}
}
}
cout<< *max_element(maxLen+1,maxLen+n+1)<<endl;
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1010;
//首先确定状态
//然后确定边界值与状态转移方程
//状态转移方程:是与前一项 还是多项之间的关系 取最大,最小
//最后的ans
// 状态 maxLen i j s1长度为i时,s2长度为j时,所有的最长公共 子序列的长度
int maxLen[maxn][maxn];
int main(){
// cout<<"dsf"<<endl;
char s1[maxn],s2[maxn];
while(cin>>s1>>s2){
int len1=strlen(s1);//s1.length();
int len2=strlen(s2);//s2.length();
for(int i=0;i<=len1;i++)
maxLen[i][0]=0;
for(int j=0;j<=len2;j++)
maxLen[0][j]=0;
for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){
if(s1[i-1]==s2[j-1])
maxLen[i][j]=maxLen[i-1][j-1]+1;
else
maxLen[i][j]=max(maxLen[i-1][j],maxLen[i][j-1]);
}
}
cout<<maxLen[len1][len2]<<endl;
}
}
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1010;
const int inf=0x3f3f3f3f;
int a[maxn],num[maxn][maxn];
int V(int m,int n){
if(m==0)
return num[1][n];
else if(m>n+1)
return inf;
else {
int ans=inf;
for(int i=m;i<=n-1;i++)
ans=min(ans,V(m-1,i)+num[i+1][n]);
return ans;
}
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++){
num[i][i]=a[i];
for(int j=i+1;j<=n;j++)
num[i][j]=num[i][j-1]*10+a[j];
}
cout<<V(m,n)<<endl;
}
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1010;
const int inf=0x3f3f3f3f;
int a[maxn],num[maxn][maxn];
int V(int m,int n){
if(m==0)
return num[1][n];
else if(m>n+1)
return inf;
else {
int ans=inf;
for(int i=m;i<=n-1;i++)
ans=min(ans,V(m-1,i)+num[i+1][n]);
return ans;
}
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++){
num[i][i]=a[i];
for(int j=i+1;j<=n;j++)
num[i][j]=num[i][j-1]*10+a[j];
}
cout<<V(m,n)<<endl;
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1010;
const int inf=0x3f3f;
int a[maxn],num[maxn][maxn];
int V[maxn][maxn];
//如何来写出 最佳加法表达式的 递推写法
//
int main(){
int n,m;
//fill(V,V+maxn*maxn,inf);
memset(V,inf,sizeof(V));
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++){
num[i][i]=a[i];
for(int j=i+1;j<=n;j++)
num[i][j]=num[i][j-1]*10+a[j];
}
if(m>n-1) cout<<inf<<endl;
for(int j=1;j<=n;j++)
V[0][j]=num[1][j];
for(int i=1;i<=m;i++){
for(int j=i+1;j<=n;j++){
for(int k=i;k<j;k++)
V[i][j]=min(V[i][j],V[i-1][k]+num[k+1][j]);
}
}
cout<<V[m][n]<<endl;
}