1.数字三角形问题
问题描述:
给定一个由n行数字组成的数字三角形如下图所示。试设计一个算法,计算出从三角形的顶至底的一条路径,使该路径经过的数字总和最大。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
问题分析:该问题的关键是,并非可以随意选择一层中的任意一个数字,路径的意思是层与层之间经过的数字是相邻的,因此不能用从n-1层递归到n层的思想。因此,本题的求解还是暴力求解,不过可以通过保存运算结果来避免重复计算,加快求解速率。
因此,建立另外一个二维数组,仅仅初始化最底层,然后不断通过对比来确定上一层,保存在二维数组中的值,是已经淘汰掉一些不可能是最优的情况,最后保存在B[0][0]的值为最大值。
代码如下:
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
int A[100][100];
int B[100][100];
for(int i=0;i<n;i++){
for(int j=0;j<=i;j++) cin>>A[i][j];
}
for(int j=0;j<n;j++) B[n-1][j] = A[n-1][j];
for(int i=n-1;i>0;i--){
for(int j=0;j<i;j++){
if(B[i][j] > B[i][j+1])
B[i-1][j] = B[i][j] + A[i-1][j];
else B[i-1][j] = B[i][j+1] + A[i-1][j];
}
}
cout<<B[0][0]<<endl;
}
2.租用游艇问题
问题描述:
长江游艇俱乐部在长江上设置了n 个游艇出租站1,2,…,n。游客可在这些游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站i 到游艇出租站j 之间的租金为r(i,j),1£i<j£n。试设计一个算法,计算出从游艇出租站1 到游艇出租站n 所需的最少租金。 要求:对于给定的游艇出租站i 到游艇出租站j 之间的租金为r(i,j),1£i<j£n,编程计算从游艇出租站1 到游艇出租站n所需的最少租金。
问题分析:该问题其实就是最短路径问题。
代码如下:
#include <iostream>
#include <limits.h>
using namespace std;
int main(){
int n;
cin>>n;
int A[201][201];
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++)
cin>>A[i][j];
}
for(int i=1;i<=n;i++){
A[i][i] = 0;
}
for(int k=2;k<n;k++) {
for(int i=1;i<=n-k;i++) {
int j=i+k;
for(int z=i+1;z<=j;z++) {
int temp = A[i][z]+A[z][j];
if(A[i][j]>temp)
A[i][j]=temp;
}
}
}
cout<<A[1][n]<<endl;
}
设I是一个n位十进制整数。如果将I划分为k段,则可得到k个整数。这k个整数的乘积称为I的一个k乘积。试设计一个算法,对于给定的I和k,求出I的最大k乘积。
问题分析:这同样是个动态规划问题,拥有最优子结构性质,可以用递推来求解。
设I(s,t)是I的从s位开始的t位数字组成的十进制数,FindMax(i,j)表示I(0,i)的最大j乘积。动态规划递推式如下:
FindMax(i,j) = max{FindMax(k,j-1)*I(k,i-k)} (1<=k<i)
代码如下:
#include <iostream>
#include <limits.h>
using namespace std;
int I(int s,int t,int A[]){
int sum = 0;
for(int i=0;i<t;i++) sum = sum*10 +A[s+i];
return sum;
}
int FindMax(int i,int j,int A[]){
if(j == 1) {
return I(0,i,A);
}
int max = 0;
for(int k=1;k<i;k++){
if((FindMax(k,j-1,A)*I(k,i-k,A)) > max ) max = (FindMax(k,j-1,A)*I(k,i-k,A));
}
return max;
}
int main(){
int n,k,num;
cin>>n>>k>>num;
int static A[11];
for(int i=n-1;i>=0;i--){
A[i] = num % 10;
num = num / 10;
}
cout<<FindMax(n,k,A)<<endl;
}