钢条切割问题
public class Main {
int n = 10;
int[] p = new int[]{1,5,8,9,10,17,17,20,24,30};
int[] r = new int[n+1];
int[] s = new int[n+1];
int solve(int n,int[] s,int c){
if(n==0) return 0;
if(r[n]>=0) return r[n];
else{
int max = -10000;
for(int i=1;i<=n;i++){
int t = p[i-1]+solve(n-i,s,c)-c;
if(t>max){
max = t;
s[n] = i;
}
}
r[n] = max;
return max;
}
}
void solve2(int n){
Arrays.fill(r, -1);
r[0] = 0;
for(int i=1;i<=n;i++){
int max = 0;
for(int j=1;j<=i;j++){
if(max<p[j-1]+r[i-j]){
max = p[j-1]+r[i-j];
s[i] = j;
}
}
r[i] = max;
}
System.out.println("最大价值为"+r[n]);
System.out.println("切割方式:");
while(n>0){
System.out.println(s[n]);
n = n-s[n];
}
}
public static void main(String[] args) {
Main m = new Main();
Arrays.fill(m.r, -1);
System.out.println(m.solve(7,m.s,1));
System.out.println(Arrays.toString(m.s));
int n = 7;
while(n>0){
System.out.println(m.s[n]);
n = n-m.s[n];
}
}
}
矩阵链乘
public class Main {
int n = 6;
int[][] m = new int[n][n];
int[][] s = new int[n][n];
int solve(int[] p){
for(int i=0;i<n;i++){
m[i][i] = 0;
}
for(int l=1;l<n;l++){//l-1为几个矩阵相乘
for(int i=0;i<n-l;i++){//i为起始
int j = i+l;//j为结束
m[i][j] = 100000;
for(int k=i;k<j;k++){//k为分割点
if(m[i][j]>m[i][k]+m[k+1][j]+p[i]*p[k+1]*p[j+1]){
m[i][j]=m[i][k]+m[k+1][j]+p[i]*p[k+1]*p[j+1];
s[i][j] = k;
}
}
}
}
return m[0][n-1];
}
int solve(int[] p,int i,int j){
if(m[i][j]>0) return m[i][j];
if(i==j) return 0;
m[i][j] = 100000;
for(int k=i;k<j;k++){
int t = solve(p, i, k)+solve(p,k+1,j)+p[i]*p[k+1]*p[j+1];
if(m[i][j]>t){
m[i][j] = t;
s[i][j] = k;
}
}
return m[i][j];
}
void print(int[][] s,int i,int j){
if(i==j){
System.out.print("A"+i);
}else{
System.out.print('(');
print(s, i, s[i][j]);
print(s, s[i][j]+1,j);
System.out.print(')');
}
}
public static void main(String[] args) {
Main m = new Main();
//System.out.println(m.solve(new int[]{5,10,3,12,5,50,6}));
//m.print(m.s,0,5);
System.out.println(m.solve(new int[]{5,10,3,12,5,50,6},0,5));
m.print(m.s,0,5);
}
}
最长公共子序列
public class Main {
void solve(char[] x,char[] y){
int m = x.length;
int n = y.length;
int c[][] = new int[m+1][n+1];
for(int i=0;i<n;i++){
c[0][i] = 0;
}
for(int i=0;i<m;i++){
c[i][0] = 0;
}
for(int i=1;i<=m;i++){//i为子序列长度
for(int j=1;j<=n;j++){//j为子序列长度
if(x[i-1]==y[j-1]){
c[i][j] = c[i-1][j-1]+1;
}else{
c[i][j] = Math.max(c[i][j-1], c[i-1][j]);
}
}
}
System.out.println(c[m][n]);
print(c, m, n, x);
}
int solve2(int c[][],char[] x,char[] y,int i,int j){
if(c[i][j]>0) return c[i][j];
if(i==0||j==0) c[i][j] = 0;
else{
if(x[i-1]==y[j-1]){
c[i][j] = solve2(c, x, y, i-1, j-1)+1;
}else{
c[i][j] = Math.max(solve2(c, x, y, i-1, j), solve2(c, x, y, i, j-1));
}
}
return c[i][j];
}
void print(int[][] c,int m,int n,char[] x){
if(m==0||n==0) return;
if(c[m][n]==c[m-1][n-1]+1){
System.out.println(x[m-1]);
print(c, m-1, n-1, x);
}else if(c[m][n]==c[m-1][n]){
print(c, m-1, n, x);
}else{
print(c, m, n-1, x);
}
}
public static void main(String[] args) {
Main m = new Main();
//m.solve("BDCABA".toCharArray(),"ABCBDAB".toCharArray());
char[] a1 = "BDCABA".toCharArray();
char[] a2 = "ABCBDAB".toCharArray();
int[][] c = new int[a1.length+1][a2.length+1];
int t = m.solve2(c, a1, a2, a1.length, a2.length);
System.out.println(t);
m.print(c, a1.length, a2.length, a1);
}
}
最长单调递增子序列
public class Main {
void solve(int[] arr){
int[] d = new int[arr.length];
d[0] = 1;
for(int i=0;i<arr.length;i++){
d[i] = 1;
for(int j=0;j<i;j++){
if(arr[i]>arr[j]){
if(d[j]+1>d[i]){
d[i] = d[j]+1;
}
}
}
}
System.out.println(d[arr.length-1]);
}
public static void main(String[] args) {
Main m = new Main();
m.solve(new int[]{1,1,2,3,4,1,2,7,5,7,1,3,4,8,9});
}
}