static int n;//钢条长度 static int p[];//价格表,p[i]:长度为i的钢条的价格 static int r[];//r[i]:长度为i的钢条的最大收益
static int r(int n) { if(n==0) return 0; int q=-1; for(int i=1;i<=n;i++) { q=Math.max(q, r(n-i)+p[i]); } return q; }缺点:对某些子问题进行多次反复的求解,大大增加了运行时间
static void r() { for(int i=1;i<=n;i++) { r[i]=0; } for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++){ r[i]=Math.max(r[i],r[i-j]+p[j]); } } }
2、求具体的切割方案
static int[] s;//s[i]:长度为i的钢条切割的第一根钢条的长度 static void r1() { for(int i=1;i<=n;i++) { r[i]=0; } for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) { if(r[i]<r[i-j]+p[j]) { r[i]=r[i-j]+p[j]; s[i]=j; } } } //打印出切割方案 while(n>0) { System.out.print(s[n]+" "); n=n-s[n]; } }
static int n;//背包容量 static int m;//石头的总数量 static int v[];//v[i]:编号为i的石头的体积 static int w[];//w[i]:编号为i的石头的重量 static int dp[][];//dp[i][j]:只考虑第编号为1~i的石头,当剩余空间为j时,能达到的最大的重量1、求能装的最大重量
static int dp(int m,int n)//n:剩余容量,m:只考虑编号为1~m的石头 { if(n==0) return 0; if(m==0) return 0; if(n<v[m]) return dp(m-1, n);//剪枝 return Math.max(dp(m-1,n-v[m]),dp(m-1,n)); }自底向上
static void dp(){ for(int i=0;i<=m;i++) { dp[i][0]=0; } for(int j=0;j<=n;j++) { dp[0][j]=0; } for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(j<v[i]) { dp[i][j]=dp[i-1][j]; } else { dp[i][j]=Math.max(dp[i-1][j-v[i]]+w[i],dp[i-1][j]); } } } }
static void print_dp() { int j=n; int s[]=new int[m+1]; for(int i=m;i>=1;i--) { if(j<v[i]) { break; } if(dp[i-1][j-v[i]]+w[i]>dp[i-1][j]) { j=j-v[i]; s[i]=1; } } //打印出用到的石头编号 for(int i=1;i<=m;i++) { if(s[i]==1) { System.out.print(i+" "); } } }
static int n;//背包的容量 static int m;//背包的种类数 static int[] v;//v[i]:编号为i的石头的体积 static int[] w;//w[i]:编号为i的石头的重量 static int[] a;//a[i]:编号为i的石头的数目 static int[][] dp;//dp[i][j]:只考虑编号为1~i的石头,若剩余空间为j,所能达到的最大重量
static int dp(int n,int m)//n:剩余容量,m:只考虑编号为1~m的石头 { if(n==0) return 0; if(m==0) return 0; int tmp=-1; for(int i=0;i<=a[m];i++) { if(n<v[m]*i) { break; } if(dp(n-i*v[m],m-1)>tmp) { tmp=dp(n-i*v[m],m-1)+i*w[i]; } } return tmp; }自底向上
static void dp() { int tmp; for(int i=1;i<=m;i++) { tmp=-1; for(int j=1;j<=n;j++) { for(int k=0;k<=a[i];k++) { if(j<k*v[i]) { break; } if(dp[i-1][j-k*v[i]]+k*w[i]>tmp) { tmp=dp[i-1][j-k*v[i]]+k*w[i]; //j=j-k*v[i]; } } dp[i][j]=tmp; } } }
static void print_dp() { int tmp=-1; int j=n; int s[]=new int[m+1];//s[i]:编号为i的石头需要的数目 for(int i=m;i>=1;i--) { for(int k=0;k<=a[i];k++) { if(j<k*v[i]) { break; } if(dp[i-1][j-v[i]*k]+k*w[i]>tmp) { tmp=dp[i-1][j-k*v[i]]+k*w[i]; j=j-k*v[i]; s[i]=k; } } } for(int i=1;i<=m;i++) { System.out.print(s[i]+" "); } }