题目:
某游戏是一个卡牌类游戏,玩家通过战斗或抽牌可以拿到一些 技能牌,每张技能牌都有对应的伤害值(伤 害值>=0),当你有 了组合技属性之后,你可以在自己手头上选择任意张技能牌, 以组合技的方式来攻击 boss,组合技的总伤害将等于所组合的 各张技能牌的伤害值的乘积(只有一张牌时,组合技伤害值等于 这张牌 本身的伤害值),但是能发动组合技必须有个前提:所有 被选择的技能牌的伤害系数之和必须等于m(m>0) 以解开封印; 你为了能赢得最终胜利,需要在所有技能牌中挑出若干张技能 牌触发组合技(每张牌只能用一 次),以形成最大威力的组合技 攻击效果。 例如:你有伤害值分别为1,2,3,4,5的五张牌,给定 的解开封印的阈值(m)为10,那形成最大组合攻击效果 的组合 为30(532),而不是24(4321),也不是20(54*1),需要输 出的结果即30。 |
---|
大致意思就是,sum一定,怎么让乘积最大
首先当然是写尝试版本的地柜:(和背包问题一样)
public static int process(int i,int[] arr,int sum) {
if(i==arr.length) {
return sum==0?1:-1;
}
// if(sum<0) {
// return -1;
// }
int a=arr[i]*process(i+1,arr,sum-arr[i]);
int b=process(i+1,arr,sum);
int max=Math.max(a, b);
return max;
}
```public static int process(int i,int[] arr,int sum) {
if(i==arr.length) {
return sum==0?1:-1;
}
// if(sum<0) {
// return -1;
// }
int a=arr[i]*process(i+1,arr,sum-arr[i]);
int b=process(i+1,arr,sum);
int max=Math.max(a, b);
return max;
}
**然后根据上面,去写dp,这里关于sum<0那个,我没有画在dp表,而是当成一个判断放在流程中了**
public static int process1(int [] arr,int sum) {
int max=0;
int s=0;
for(int i=0;i<arr.length;i++) {
s+=arr[i];
}
int[][] dp=new int[arr.length+1][sum+1];
//初始化,记住sum《0那个不在这里,我加到判断里面了
dp[arr.length][0]=1;
for(int i=1;i<=sum;i++) {
dp[arr.length][i]=-1;
}
for(int i=arr.length-1;i>=0;i--) {
for(int j=0;j<=sum;j++) {
int a,b;
if(j-arr[i]<0) {
a=arr[i]*(-1);
}else {
a=arr[i]*dp[i+1][j-arr[i]];
}
b=dp[i+1][j];
dp[i][j]=Math.max(a, b);
}
}
return dp[0][sum];
}
**上面是左神讲的一个题**