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; }