dp1

在进行递归的过程中 往往会出现重复计算,而这个过程会比较浪费时间,往往会浪费掉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;	 
	 
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值