租用游艇问题
思想:动态规划。满足最优子结构。
设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).