java algorithm 包_java - 算法 - 依赖背包

import java.util.*;public classMain{public static voidmain(String[] args){

Scanner s= newScanner(System.in);int n = s.nextInt(); //总钱数

int m = s.nextInt(); //总个数

int[] v = new int[m + 1]; //价格

int[] p = new int[m + 1]; //重要度 1 - 5

int[] q = new int[m + 1]; //类型 0主键 >0附件

int[] zj = new int[m + 1];int zjIndex = 1;for(int i = 1; i <= m; i++){

v[i]=s.nextInt();

p[i]=s.nextInt();

q[i]=s.nextInt();if(q[i] == 0){

zj[zjIndex]=i;

zjIndex++;

}

}int[][] value = new int[m+1][n+1];for(int ii = 1; ii <= zj.length; ii++){ //物品

if(zj[ii] == 0){break;

}int i =zj[ii];for(int j = 1; j < n+1; j++){ //价格//value[i][j] 当前最大价值

if(q[i] == 0) { //当前为主键时

if (j >=v[i]) {

value[i][j]= Math.max(value[zj[ii - 1]][j], value[zj[ii - 1]][j - v[i]] + v[i] *p[i]);

}else{

value[i][j]= value[zj[ii - 1]][j];

}//处理附件

int fj1 = -1;int fj2 = -1;//寻找第一个附件

for(int k = 1; k <= m; k++){if(q[k] ==i){

fj1=k;break;

}

}//寻找第二个附件

for(int k = 1; k <= m; k++){if(q[k] == i && k !=fj1){

fj2=k;break;

}

}//处理第1个附件(把主件和第1个附件都放入背包)//把主件和附件1看做一体

int vv1 = 0;if ( fj1 != -1 && j- 1 >= v[i] +v[fj1]) {int v1 = value[zj[ii - 1]][j];int v2 = value[zj[ii - 1]][j - v[i] - v[fj1]] + v[i] * p[i] + v[fj1] *p[fj1];

vv1=Math.max( v1 , v2 );

}else{

vv1= value[zj[ii - 1]][j];

}//处理第2个附件(把主件和第2个附件都放入背包)

int vv2 = 0;if (fj2 != -1 && j- 1 >= v[i] +v[fj2]) {int v1 = value[zj[ii - 1]][j];int v2 = value[zj[ii - 1]][j - v[i] - v[fj2]] + v[i] * p[i] + v[fj2] *p[fj2];

vv2=Math.max( v1 , v2 );

}else{

vv2= value[zj[ii - 1]][j];

}//处理第1 + 2个附件(把主件和两个附件都放入背包)

int vv3 = 0;if (fj1 != -1 && fj2 != -1 && j- 1 >= v[i] + v[fj1] +v[fj2]) {int v1 = value[zj[ii - 1]][j];int v2 = value[zj[ii - 1]][j - v[i] - v[fj1] - v[fj2]] + v[i] * p[i] + v[fj1] * p[fj1] + v[fj2] *p[fj2];

vv3=Math.max( v1 , v2 );

}else{

vv3= value[zj[ii - 1]][j];

}int vmax1 =Math.max(value[i][j], vv1);int vmax2 =Math.max(vv2, vv3);

value[i][j]=Math.max(vmax1, vmax2);

}

}

}for(int i = m; i > 0 ; i--) {if(q[i] == 0) {

System.out.println(value[i][n]);break;

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值