标签:相关 遍历 字符 不用 std ade max 规模 绝对值
//program 4-1
#include <iostream>
#include<cstring>
using namespace std;
const int N=1002;
int c[N][N],b[N][N];
char s1[N],s2[N];
int len1,len2;
void LCSL()
{
int i,j;
for(i = 1;i <= len1;i++)//控制s1序列不同的子问题
for(j = 1;j <= len2;j++)//控制s2序列不同的子问题
{
if(s1[i-1]==s2[j-1])
{
c[i][j] = c[i-1][j-1]+1;//如果当前字符相同,则公共子序列的长度为该字符前的最长公共序列+1
b[i][j] = 1;
}
else
{
if(c[i][j-1]>=c[i-1][j])
{
c[i][j] = c[i][j-1];
b[i][j] = 2;
}
else
{
c[i][j] = c[i-1][j];
b[i][j] = 3;
}
}
}
}
void print(int i, int j)//根据记录下来的信息构造最长公共子序列(从b[i][j]开始递推)
{
if(i==0 || j==0) return;
if(b[i][j]==1)
{
print(i-1,j-1);
cout<<s1[i-1];
}
else if(b[i][j]==2)
print(i,j-1);
else
print(i-1,j);
}
int main()
{
int i,j;
cout << "输入字符串s1:"<<endl;
cin >> s1;
cout << "输入字符串s2:"<<endl;
cin >> s2;
len1 = strlen(s1);//计算两个字符串的长度
len2 = strlen(s2);
for(i = 0;i <= len1;i++)
{
c[i][0]=0;//初始化第一列为0
}
for(j = 0;j<= len2;j++)
{
c[0][j]=0;//初始化第一行为0
}
LCSL();
cout << "s1和s2的最长公共子序列长度是:"<<c[len1][len2]<<endl;
cout << "s1和s2的最长公共子序列是:";
print(len1,len2);
cout<<endl;
// /*用于测试
cout<<"c[i][j]数组:"<<endl;
for(i = 0;i <= len1;i++)
{
for(j = 0;j <= len2;j++)
cout <<" "<<c[i][j];
cout<<endl;
}
cout<<"b[i][j]数组:"<<endl;
for(i = 0;i <= len1;i++)
{
for(j = 0;j <= len2;j++)
cout <<" "<<b[i][j];
cout<<endl;
}
// */用于测试
return 0;
}
//program 4-2
#include <iostream>
#include <cstring>
using namespace std;
const int N=100;
char str1[N],str2[N];
int d[N][N]; //定义辅助数组,d[i][j]表示str1前i个字符和str2前j个字符的编辑距离。
int min(int a, int b)
{
return a<b?a:b;//返回较小的值
}
int editdistance(char *str1, char *str2)
{
int len1 = strlen(str1);
int len2 = strlen(str2);//取字符串大小
for(int i=0;i<=len1;i++)//当第二个串长度为0,编辑距离初始化为i
d[i][0]= i;
for(int j=0;j<=len2;j++)//当第一个串长度为0,编辑距离初始化为j
d[0][j]=j;
for(int i=1;i <=len1;i++)//遍历两个数组
{
for(int j=1;j<=len2;j++)
{
int diff;//判断str[i]是否等于str2[j],相等为0,代表不用改变str1,不相等为1,代表需要改变str1。
if(str1[i-1] == str2[j-1])//相等
diff = 0 ;
else
diff = 1 ;
int temp = min(d[i-1][j] + 1, d[i][j-1] + 1);//先两者取最小值
d[i][j] = min(temp, d[i-1][j-1] + diff);//再取最小值,相当于三者取最小值d[i-1][j] + 1, d[i][j-1] + 1,d[i-1][j-1] + diff
}
}
return d[len1][len2];
}
int main()
{
cout << "输入字符串str1:"<<endl;
cin >> str1;
cout << "输入字符串str2:"<<endl;
cin >> str2;
cout << str1<< "和"<<str2<<"的编辑距离是:"<<editdistance(str1,str2);
return 0;
}
//program 4-3
#include<iostream>
using namespace std;
const int ms = 1000;
int r[ms][ms],m[ms][ms],s[ms][ms]; //i到j站的租金
int n; //共有n个站点
void rent()
{
int i,j,k,d;
for(d=3;d<=n;d++) //将问题分为小规模为d
{
for(i=1;i<=n-d+1;i++)
{
j=i+d-1;
for(k=i+1;k<j;k++) //记录每一个小规模内的最优解
{
int temp;
temp=m[i][k]+m[k][j];
if(temp<m[i][j])
{
m[i][j]=temp;
s[i][j]=k;
}
}
}
}
}
void print(int i,int j)
{
if(s[i][j]==0 )
{
cout << "--"<<j;
return ;
}
print(i,s[i][j]);
print(s[i][j],j);
}
int main()
{
int i,j;
cout << "请输入站点的个数 n:";
cin >> n;
cout << "请依次输入各站点之间的租金:";
for(i=1;i<=n;i++)
for(j=i+1;j<=n;++j)
{
cin>>r[i][j];
m[i][j]=r[i][j];
}
rent();
cout << "花费的最少租金为:" <<m[1][n] << endl;
cout <<"最少租金经过的站点:"<<1;
print(1,n);
// /*用于测试 输出m[][]和s[][]数组
cout << endl;
for (i = 1; i <= n; i++ )
{
for (j = 1; j <=2*(i-1); j++ )
cout << " " ;
for (j=i; j<=n;j++ )
cout << m[i][j]<<" " ;
cout << endl;
}
for (i=1; i<=n;i++ )
{
for (j =1; j <=2*(i-1);j++ )
cout << " " ;
for (j=i; j<=n; j++ )
cout << s[i][j]<<" " ;
cout << endl;
}
cout << endl;
// /*/用于测试
return 0;
}
//program 4-4
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int msize = 100;
int p[msize];
int m[msize][msize];
int s[msize][msize];
int n;
void matrixchain()
{
int i,j,r,k;
memset(m,0,sizeof(m));
memset(s,0,sizeof(s));
for(r = 2; r <= n; r++) //不同规模的子问题
{
for(i = 1; i <= n-r+1; i++)
{
j = i + r - 1;
m[i][j] = m[i+1][j] + p[i-1] * p[i] * p[j]; //决策为k=i的乘法次数
s[i][j] = i; //子问题的最优策略是i;
for(k = i+1; k < j; k++) //对从i到j的所有决策,求最优值,记录最优策略
{
int t = m[i][k] + m[k+1][j] + p[i-1] * p[k] * p[j];
if(t < m[i][j])
{
m[i][j] = t;
s[i][j] = k;
}
}
}
}
}
void print(int i,int j)
{
if( i == j )
{
cout <<"A[" << i << "]";
return ;
}
cout << "(";
print(i,s[i][j]);
print(s[i][j]+1,j);
cout << ")";
}
int main()
{
cout << "请输入矩阵的个数 n:";
cin >> n;
int i ,j;
cout << "请依次输入每个矩阵的行数和最后一个矩阵的列数:";
for (i = 0; i <= n; i++ )
cin >> p[i];
matrixchain();
print(1,n);
cout << endl;
/*用于测试
for (i = 1; i <= n; i++ )
{
for (j = i; j <= n; j++ )
cout << m[i][j]<<" " ;
cout << endl;
}
for (i = 1; i <= n; i++ )
{
for (j = i; j <= n; j++ )
cout << s[i][j]<<" " ;
cout << endl;
}
cout << endl;
*/
cout << "最小计算量的值为 " << m[1][n] << endl;
}
//program 4-5
#include<iostream>
#include<sstream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std ;
const int M= 1000 + 5 ;
int n ;
int s[M][M] ;
double m[M][M],g[M][M];
void Convexpolygontriangulation()
{
for(int i = 1 ;i <= n ; i++) // 初始化
{
m[i][i] = 0 ;
s[i][i] = 0 ;
}
for(int d = 2 ;d <= n ; d++) // 枚举点的个数
for(int i = 1 ;i <= n - d + 1 ; i++) // 枚举起始点
{
int j = i + d - 1 ; // 终点
m[i][j] = m[i+1][j] + g[i-1][i] + g[i][j] + g[i-1][j] ;
s[i][j] = i ;
for(int k = i + 1 ;k < j ; k++) // 枚举中间点
{
double temp = m[i][k] + m[k+1][j] + g[i-1][k] + g[k][j] + g[i-1][j] ;
if(m[i][j] > temp)
{
m[i][j] = temp ; // 更新最优值
s[i][j] = k ; // 记录中间点
}
}
}
}
void print(int i , int j) // 输出所有的弦
{
if(i == j) return ;
if(s[i][j]>i)
cout<<"{v"<<i-1<<"v"<<s[i][j]<<"}"<<endl;
if(j>s[i][j]+1)
cout<<"{v"<<s[i][j]<<"v"<<j<<"}"<<endl;
print(i ,s[i][j]);
print(s[i][j]+1 ,j);
//cout<<"{ v"<<i-1<<" , v"<<s[i][j]<<" , v"<<j<<" }"<<endl; //输出所有剖分后的三角形
}
int main()
{
int i,j;
cout << "请输入顶点的个数 n:";
cin >> n;
n-- ;
cout << "请依次输入各顶点的连接权值:";
for(int i = 0 ;i <= n ; i++) // 输入各个顶点之间的距离
for(int j = 0 ;j <= n ; j++)
cin>>g[i][j] ;
Convexpolygontriangulation();
cout<<m[1][n]<<endl;
// /*用于测试 输出m[][]和s[][]数组
for (i = 1; i <= n; i++ )
{
for (j = 1; j <=2*(i-1); j++ )
cout << " " ;
for (j = i; j <= n; j++ )
cout << m[i][j]<<" " ;
cout << endl;
}
for (i = 1; i <= n; i++ )
{
for (j = 1; j <=2*(i-1); j++ )
cout << " " ;
for (j = i; j <= n; j++ )
cout << s[i][j]<<" " ;
cout << endl;
}
cout << endl;
// /*/用于测试
print(1 ,n); // 打印路径
return 0 ;
}
//program 4-6
#include <iostream>
#include <string>
using namespace std;
const int INF = 1 << 30;
const int N = 205;
int Min[N][N], Max[N][N];
int sum[N];
int a[N];
int min_Circular,max_Circular;
void straight(int a[],int n)
{
for(int i=1;i<=n;i++) // 初始化
Min[i][i]=0, Max[i][i]=0;
sum[0]=0;
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+a[i];
for(int v=2; v<=n; v++) // 枚举合并的堆数规模
{
for(int i=1; i<=n-v+1; i++) //枚举起始点i
{
int j = i + v-1; //枚举终点j
Min[i][j] = INF; //初始化为最大值
Max[i][j] = -1; //初始化为-1
int tmp = sum[j]-sum[i-1];//记录i...j之间的石子数之和
for(int k=i; k<j; k++) { //枚举中间分隔点
Min[i][j] = min(Min[i][j], Min[i][k] + Min[k+1][j] + tmp);
Max[i][j] = max(Max[i][j], Max[i][k] + Max[k+1][j] + tmp);
}
}
}
}
void Circular(int a[],int n)
{
for(int i=1;i<=n-1;i++)
a[n+i]=a[i];
n=2*n-1;
straight(a, n);
n=(n+1)/2;
min_Circular=Min[1][n];
max_Circular=Max[1][n];
for(int i=2;i<=n;i++)
{
if(Min[i][n+i-1]<min_Circular)
min_Circular=Min[i][n+i-1];
if(Max[i][n+i-1]>max_Circular)
max_Circular=Max[i][n+i-1];
}
}
int main()
{
int n;
cout << "请输入石子的堆数 n:";
cin >> n;
cout << "请依次输入各堆的石子数:";
for(int i=1;i<=n;i++)
cin>>a[i];
straight(a, n);
cout<<"路边玩法(直线型)最小花费为:"<<Min[1][n]<<endl;
cout<<"路边玩法(直线型)最大花费为:"<<Max[1][n]<<endl;
Circular(a,n);
cout<<"操场玩法(圆型)最小花费为:"<<min_Circular<<endl;
cout<<"操场玩法(圆型)最大花费为:"<<max_Circular<<endl;
return 0;
}
//program 4-6-1
#include <iostream>
#include <string>
using namespace std;
const int INF = 1 << 30;
const int N = 205;
int Min[N][N], Max[N][N],s[N][N];
int sum[N];
int a[N];
int min_Circular,max_Circular;
void get_Min(int n)
{
for(int v=2; v<=n; v++) // 枚举合并的堆数规模
{
for(int i=1; i<=n-v+1; i++) //枚举起始点i
{
int j = i + v-1; //枚举终点j
int tmp = sum[j]-sum[i-1];//记录i...j之间的石子数之和
int i1=s[i][j-1]>i?s[i][j-1]:i;
int j1=s[i+1][j]<j?s[i+1][j]:j;
Min[i][j]=Min[i][i1]+Min[i1+1][j];
s[i][j]=i1;
for(int k=i1+1; k<=j1; k++) //枚举中间分隔点
if(Min[i][k]+ Min[k+1][j]<Min[i][j])
{
Min[i][j]=Min[i][k]+Min[k+1][j];
s[i][j]=k;
}
Min[i][j]+=tmp;
}
}
}
void get_Max(int n)
{
for(int v=2; v<=n; v++) // 枚举合并的堆数规模
{
for(int i=1; i<=n-v+1; i++) //枚举起始点i
{
int j = i + v-1; //枚举终点j
Max[i][j] = -1; //初始化为-1
int tmp = sum[j]-sum[i-1];//记录i...j之间的石子数之和
if(Max[i+1][j]>Max[i][j-1])
Max[i][j]=Max[i+1][j]+tmp;
else
Max[i][j]=Max[i][j-1]+tmp;
}
}
}
void straight(int a[],int n)
{
for(int i=1;i<=n;i++) // 初始化
Min[i][i]=0, Max[i][i]=0, s[i][i]=0;
sum[0]=0;
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+a[i];
get_Min(n);
get_Max(n);
}
void Circular(int a[],int n)
{
for(int i=1;i<=n-1;i++)
a[n+i]=a[i];
n=2*n-1;
straight(a, n);
n=(n+1)/2;
min_Circular=Min[1][n];
max_Circular=Max[1][n];
for(int i=2;i<=n;i++)
{
if(Min[i][n+i-1]<min_Circular)
min_Circular=Min[i][n+i-1];
if(Max[i][n+i-1]>max_Circular)
max_Circular=Max[i][n+i-1];
}
}
int main()
{
int n;
cout << "请输入石子的堆数 n:";
cin >> n;
cout << "请依次输入各堆的石子数:";
for(int i=1;i<=n;i++)
cin>>a[i];
straight(a, n);
cout<<"路边玩法(直线型)最小花费为:"<<Min[1][n]<<endl;
cout<<"路边玩法(直线型)最大花费为:"<<Max[1][n]<<endl;
Circular(a,n);
cout<<"操场玩法(圆型)最小花费为:"<<min_Circular<<endl;
cout<<"操场玩法(圆型)最大花费为:"<<max_Circular<<endl;
return 0;
}
//program 4-7
#include <iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 10005
#define M 105
int c[M][maxn];//c[i][j] 表示前i个物品放入容量为j购物车获得的最大价值
int w[M],v[M];//w[i] 表示第i个物品的重量,v[i] 表示第i个物品的价值
int x[M]; //x[i]表示第i个物品是否放入购物车
int main(){
int i,j,n,W;//n表示n个物品,W表示购物车的容量
cout << "请输入物品的个数 n:";
cin >> n;
cout << "请输入购物车的容量W:";
cin >> W;
cout << "请依次输入每个物品的重量w和价值v,用空格分开:";
for(i=1;i<=n;i++)
cin>>w[i]>>v[i];
for(i=1;i<=n;i++)//初始化第0列为0
c[i][0]=0;
for(j=1;j<=W;j++)//初始化第0行为0
c[0][j]=0;
for(i=1;i<= n;i++)//计算c[i][j]
for(j=1;j<=W;j++)
if(j<w[i]) //当物品的重量大于购物车的容量,则不放此物品
c[i][j] = c[i-1][j];
else //否则比较此物品放与不放是否能使得购物车内的价值最大
c[i][j] = max(c[i-1][j],c[i-1][j-w[i]] + v[i]);
cout<<"装入购物车的最大价值为:"<<c[n][W]<<endl;
//用于测试
for (i=1; i<=n; i++ )
{
for (j=1; j<=W; j++ )
cout << c[i][j]<<"\t" ;
cout << endl;
}
cout << endl;
//逆向构造最优解
j=W;
for(i=n;i>0;i--)
if(c[i][j]>c[i-1][j])
{
x[i]=1;
j-=w[i];
}
else
x[i]=0;
cout<<"装入购物车的物品序号为:";
for(i=1;i<=n;i++)
if(x[i]==1)
cout<<i<<" ";
return 0;
}
//program 4-7
#include <iostream>
#include<cstring>
using namespace std;
#define maxn 10005
#define M 105
int dp[maxn];//dp[j] 表示当前已放入容量为j的购物车获得的最大价值
int w[M],v[M];//w[i] 表示第i个物品的重量,v[i] 表示第i个物品的价值
int x[M]; //x[i]表示第i个物品是否放入购物车
int i,j,n,W;//n表示n个物品,W表示购物车的容量
void opt1(int n,int W)
{
for(i=1;i<=n;i++)
for(j=W;j>0;j--)
if(j>=w[i]) //当物品的重量大于购物车的容量,比较此物品放与不放是否能使得购物车内的价值最大
dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
}
void opt2(int n,int W)
{
for(i=1;i<= n;i++)
for(j=W;j>=w[i];j--)
//当物品的重量大于购物车的容量,比较此物品放与不放是否能使得购物车内的价值最大
dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
}
void opt3(int n,int W)
{
int sum[n];//sum[i]表示从1...i的物品重量之和
sum[0]=0;
for(i=1;i<=n;i++)
sum[i]=sum[i-1]+w[i];
for(i=1;i<=n;i++)
{
int bound=max(w[i],W-(sum[n]-sum[i-1]));//w[i]与剩余容量取最大值,sum[n]-sum[i-1]表示从i...n的物品重量之和
for(j=W;j>=bound;j--)
//当物品的重量大于购物车的容量,比较此物品放与不放是否能使得购物车内的价值最大
dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
}
}
int main()
{
cout << "请输入物品的个数 n:";
cin >> n;
cout << "请输入购物车的容量W:";
cin >> W;
cout << "请依次输入每个物品的重量w和价值v,用空格分开:";
for(i=1;i<=n;i++)
cin>>w[i]>>v[i];
for(j=1;j<=W;j++)//初始化第0行为0
dp[j]=0;
opt1(n,W);
//opt2(n,W);
//opt3(n,W);
cout<<"装入购物车的最大价值为:"<<dp[W]<<endl;
//测试dp[]数组结果
for(j=1;j<=W;j++)
cout<<dp[j]<<" ";
cout<<endl;
/* //逆向构造最优解,无法构造最优解
j=W;
for(i=n;i>0;i--)
{
while(dp[j]==dp[j-1])
j--;
if(dp[j]<=(dp[j-w[i]]+v[i]))
{
x[i]=1;
j-=w[i];
}
else
x[i]=0;
}
cout<<"装入购物车的物品为:";
for(i=1;i<=n;i++)
if(x[i]==1)
cout<<i<<" ";
*/
return 0;
}
//program 4-8
#include<iostream>
#include<cmath> //求绝对值函数需要引入该头文件
using namespace std;
const int M=1000+5;
double c[M][M],w[M][M],p[M],q[M];
int s[M][M];
int n,i,j,k;
void Optimal_BST()
{
for(i=1;i<=n+1;i++)
{
c[i][i-1]=0.0;
w[i][i-1]=q[i-1];
}
for(int t=1;t<=n;t++)//t为关键字的规模
//从下标为i开始的关键字到下标为j的关键字
for(i=1;i<=n-t+1;i++)
{
j=i+t-1;
w[i][j]=w[i][j-1]+p[j]+q[j];
c[i][j]=c[i][i-1]+c[i+1][j];//初始化
s[i][j]=i;//初始化
//选取i+1到j之间的某个下标的关键字作为从i到j的根,如果组成的树的期望值当前最小,则k为从i到j的根节点
for(k=i+1;k<=j;k++)
{
double temp=c[i][k-1]+c[k+1][j];
if(temp<c[i][j]&&fabs(temp-c[i][j])>1E-6)//C++中浮点数因为精度问题不可以直接比较
{
c[i][j]=temp;
s[i][j]=k;//k即为从下标i到j的根节点
}
}
c[i][j]+=w[i][j];
}
}
void Construct_Optimal_BST(int i,int j,bool flag)
{
if(flag==0)
{
cout<<"S"<<s[i][j]<<" 是根"<<endl;
flag=1;
}
int k=s[i][j];
//如果左子树是叶子
if(k-1<i)
{
cout<<"e"<<k-1<<" is the left child of "<<"S"<<k<<endl;
}
//如果左子树不是叶子
else
{
cout<<"S"<<s[i][k-1]<<" is the left child of "<<"S"<<k<<endl;
Construct_Optimal_BST(i,k-1,1);
}
//如果右子树是叶子
if(k>=j)
{
cout<<"e"<<j<<" is the right child of "<<"S"<<k<<endl;
}
//如果右子树不是叶子
else
{
cout<<"S"<<s[k+1][j]<<" is the right child of "<<"S"<<k<<endl;
Construct_Optimal_BST(k+1,j,1);
}
}
int main()
{
cout << "请输入关键字的个数 n:";
cin >> n;
cout<<"请依次输入每个关键字的搜索概率:";
for (i=1; i<=n; i++ )
cin>>p[i];
cout << "请依次输入每个虚结点的搜索概率:";
for (i=0; i<=n; i++)
cin>>q[i];
Optimal_BST();
// /*用于测试
for(i=1; i<=n+1;i++)
{
for (j=1; j<i;j++)
cout <<"\t" ;
for(j=i-1;j<=n;j++)
cout << w[i][j]<<"\t" ;
cout << endl;
}
for(i=1; i<=n+1;i++)
{
for (j=1; j<i;j++)
cout <<"\t" ;
for(j=i-1; j<=n;j++)
cout << c[i][j]<<"\t" ;
cout << endl;
}
for(i=1; i<=n;i++)
{
for (j=1; j<i;j++)
cout << "\t" ;
for(j=i-1; j<=n;j++)
cout << s[i][j]<<"\t" ;
cout << endl;
}
cout << endl;
// */用于测试
cout<<"最小的搜索成本为:"<<c[1][n]<<endl;
cout<<"最优二叉搜索树为:";
Construct_Optimal_BST(1,n,0);
return 0;
}
//program 4-8-1
#include<iostream>
#include<cmath> //求绝对值函数需要引入该头文件
using namespace std;
const int M=1000+5;
double c[M][M],w[M][M],p[M],q[M];
int s[M][M];
int n,i,j,k;
void Optimal_BST()
{
for(i=1;i<=n+1;i++)
{
c[i][i-1]=0.0;
w[i][i-1]=q[i-1];
}
for(int t=1;t<=n;t++)//t为关键字的规模
//从下标为i开始的关键字到下标为j的关键字
for(i=1;i<=n-t+1;i++)
{
j=i+t-1;
w[i][j]=w[i][j-1]+p[j]+q[j];
int i1=s[i][j-1]>i?s[i][j-1]:i;
int j1=s[i+1][j]<j?s[i+1][j]:j;
c[i][j]=c[i][i1-1]+c[i1+1][j];//初始化
s[i][j]=i1;//初始化
//选取i1+1到j1之间的某个下标的关键字作为从i到j的根,如果组成的树的期望值当前最小,则k为从i到j的根节点
for(k=i1+1;k<=j1;k++)
{
double temp=c[i][k-1]+c[k+1][j];
if(temp<c[i][j]&&fabs(temp-c[i][j])>1E-6)//C++中浮点数因为精度问题不可以直接比较
{
c[i][j]=temp;
s[i][j]=k;//k即为从下标i到j的根节点
}
}
c[i][j]+=w[i][j];
}
}
void Construct_Optimal_BST(int i,int j,bool flag)
{
if(flag==0)
{
cout<<"S"<<s[i][j]<<" 是根"<<endl;
flag=1;
}
int k=s[i][j];
//如果左子树是叶子
if(k-1<i)
{
cout<<"e"<<k-1<<" is the left child of "<<"S"<<k<<endl;
}
//如果左子树不是叶子
else
{
cout<<"S"<<s[i][k-1]<<" is the left child of "<<"S"<<k<<endl;
Construct_Optimal_BST(i,k-1,1);
}
//如果右子树是叶子
if(k>=j)
{
cout<<"e"<<j<<" is the right child of "<<"S"<<k<<endl;
}
//如果右子树不是叶子
else
{
cout<<"S"<<s[k+1][j]<<" is the right child of "<<"S"<<k<<endl;
Construct_Optimal_BST(k+1,j,1);
}
}
int main()
{
cout << "请输入关键字的个数 n:";
cin >> n;
cout<<"请依次输入每个关键字的搜索概率:";
for (i=1; i<=n; i++ )
cin>>p[i];
cout << "请依次输入每个虚结点的搜索概率:";
for (i=0; i<=n; i++)
cin>>q[i];
Optimal_BST();
// /*用于测试
for(i=1; i<=n+1;i++)
{
for (j=1; j<i;j++)
cout <<"\t" ;
for(j=i-1;j<=n;j++)
cout << w[i][j]<<"\t" ;
cout << endl;
}
for(i=1; i<=n+1;i++)
{
for (j=1; j<i;j++)
cout <<"\t" ;
for(j=i-1; j<=n;j++)
cout << c[i][j]<<"\t" ;
cout << endl;
}
for(i=1; i<=n;i++)
{
for (j=1; j<i;j++)
cout << "\t" ;
for(j=i-1; j<=n;j++)
cout << s[i][j]<<"\t" ;
cout << endl;
}
cout << endl;
// */用于测试
cout<<"最小的搜索成本为:"<<c[1][n]<<endl;
cout<<"最优二叉搜索树为:";
Construct_Optimal_BST(1,n,0);
return 0;
}
标签:相关 遍历 字符 不用 std ade max 规模 绝对值
原文地址:https://www.cnblogs.com/self-confidence/p/13604463.html