游艇租借与数字三角形(dp)

租用游艇问题

  思想:动态规划。满足最优子结构。

设r(i,j)表示游艇出租站i到j之间的租金

  m(i,j)表示从出租站i出发,到达第i+j站需要的最少租金

  例如m(1,3)就表示从第1站出发,到达第4站所需的最少租金

  由此可以得出递归式:

  m(i,j) = min{ m(i,s)+m(i+s,j-s) , r(i,i+j) }  2≤j≤n-i ,1≤s < j

  且m(i,1) = r(i,i+1);m(n,1) = 0。

   Solve(n)函数计算最优值,最优解即为,m(1,n-1)。源码中即为m[1][n-1];

#include<iostream>
#define MAX 10050
#define INF 0x3f3f3f3f 
using namespace std;
int a[MAX][MAX]={0};

void Solve(int n)
{
	int m[n+1][n+1];
	for(int i=1;i<=n;i++){
		if(i==n) m[i][1]=0;
		else m[i][1]=a[i][i+1];
		
		for(int j=2;j<=n;j++){
			m[i][j]=INF;
			m[n][j]=0;		
		}
	} 
	
	for(int i=n-1;i>=1;i--){
		for(int j=2;j<=n-i;j++){
			for(int k=1;k<j;k++){
				int minNum;
				minNum=min(m[i][k]+m[i+k][j-k],a[i][i+j]);
				if(minNum<m[i][j])
					m[i][j]=minNum;
			}
		}
	}
	cout<<m[1][n-1];
}
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<n;i++){
		for(int j=i+1;j<=n;j++)
			cin>>a[i][j];
	}
	Solve(n);
	return 0;
 } 

最坏时间复杂度应为O(n^3);

数字三角形问题

  思想:设sum[i][j]表示数字三角形s[i][j]的最大值,则最后一行的最大值sum[n][k](1<=k<=n)=s[n][k],即为他们本身,从底向上依次递归,由此可得递归式为:

sum[i][j]=max(sum[i+1,j],sum[i+1][j+1])+s[i][j];  1<=i<=n-1;1<=j<=n-1;

初值为原三角形中最后一行的值,即

Sum[n][k]=s[n][k]   1<=k<=n;

源码中使用原数组代替sum数组,max_line()函数后,s数组的现在的值即为最优的值,即本点到最后一行的最大和值,s[1][1]即为最优解。

#include<iostream>
#include<fstream>
using namespace std;

void Max_line(int **s,int n)
{
	for(int i=n-1;i>0;i--){
		for(int j=1;j<=n-1;j++)
		s[i][j]=max(s[i+1][j],s[i+1][j+1])+s[i][j];
	}
	
}
int main()
{
	ifstream in("input2.txt");
	if(!in.is_open()){
		cout<<"error"<<endl;
		return 0;
	}
	int n;
	in>>n;
	
	int **s=new int*[n+1];
	s[0]=new int[(n+1)*(n+1)];
	for(int i=1;i<n+1;i++)
		s[i]=s[i-1]+(n+1);
		
/*	int **sum=new int*[n+1];
	sum[0]=new int[(n+1)*(n+1)];
	for(int i=1;i<n+1;i++)
		sum[i]=sum[i-1]+(n+1);
*/	
	for(int i=0;i<n+1;i++)
		for(int j=0;j<n+1;j++)
			s[i][j]=-1;
			 
	for(int i=1;i<n+1;i++)
		for(int j=1;j<=i;j++)
			in>>s[i][j];
	
	Max_line(s,n);
	ofstream out("output2.txt");
	if(!out.is_open()){
		cout<<"error out"<<endl;
		return 0;
	}
	cout<<s[1][1];
		out<<s[1][1];
}

最坏时间复杂度应为O(n^2).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值