1.以所经过的权值之和最大值为例进行说明。
行进的过程中,每次只有两种选择:向左或向右。一个有n层的数字三角形的完整路径有2n条,所以当n比较大的时候,搜索全部路径,从中找出最大值,效率较低。
采用动态规划方法实现。
用d(i,j)表示从位置(i,j)出发时得到的最大值(包括位置(i,j)本身),可以写出最大值的递归方程:
由于递归方程中包含了重复子问题,直接采用递归方程求解, 效率较低。采用动态规划的方法,用一张二维表记录中间过程的值,可以把时间效率提高到n2。
代码:
import java.util.Scanner;
public class ShuTa {
void TheBest(int a[][],int n,int m){
int b[][]=new int[m][n];
int c[][]=new int[m][n];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
b[i][j]=a[i][j];
}
}
for(int i=n-2;i>=0;i--){
for(int j=0;j<=i;j++)
{
if(a[i+1][j]>a[i+1][j+1])
{
a[i][j]=a[i][j]+a[i+1][j];
c[i][j]=0;//b表示向下走
}
else
{
a[i][j]=a[i][j]+a[i+1][j+1];
c[i][j]=1; //表示向右下方走
}
}
}
int j=0;
System.out.print("输出最大值为:");
System.out.println(a[0][0]);
for(int i=0;i<n;i++)
{
System.out.print(b[i][j]+"->");
j=j+c[i][j];
}
}
public static void main(String[] args) {
int x[][]=new int[5][5];
Scanner scanner=new Scanner(System.in);
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
x[i][j]=scanner.nextInt();
x[i][j]=x[i][j];
}
}
ShuTa sh=new ShuTa();
sh.TheBest(x, 5, 5);
}
}
截图:
用f[i]表示以ai为结尾的最长上升子序列的长度,可建立如下递归方程:
f[ ]是单调递增的,因为如果有i<j且f[i]>=f[j],那么f[i]必定可以被f[j]的内容所更新。
每处理到一个ai,要找到一个k满足f[k–1]<ai且f[k]>= ai,并用ai更新f[k],最终max{k|f[k]!=∞}就是答案。
代码:
public class LIS {
void lis(int A[],int n){
int i,j;
int f[]=new int [A.length];
int len=1;
for( i=0;i<n;i++){
f[i]=1;
for(j=0;j<i;j++){
if(A[j]<=A[i]&&(f[j]+1>=f[i]))
f[i]=f[j]+1;
}
if(f[i]>len){
len=f[i];
}
}
System.out.print("最长上升子序列的长度为:");
System.out.println(len);
}
public static void main(String[] args) {
int X[]=new int[10];
Scanner scanner=new Scanner(System.in);
System.out.print("输入一组数为:");
for(int i=0;i<10;i++){
X[i]=scanner.nextInt();
}
LIS ls=new LIS();
ls.lis(X, 10);
}
}
截图: