java在某射击场有n个靶_Leetcode 312: Burst Balloons

Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins. Here left and right are adjacent indices of i. After the burst, the left and right then becomes adjacent.

Find the maximum coins you can collect by bursting the balloons wisely.

Note:

(1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them.

(2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100

Example:

Given [3, 1, 5, 8]

Return 167

nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []

coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167

解答

这题真不赖,阿里的编程测试用了这个例子的变形,单是做出这一题就不容易了,别说它的变形了。

题目给了一个小提示,原数组的头和尾加上一个1,这个1仅仅作为求coins的一个因数。

我这脑袋瓜没想出来咋整,我就把学来的说一说。

答:是的,又是动态规划。

dp[i][j] 表示数组中 i 到 j 爆掉的coins最大值。这里的数组是加了头尾的新数组。

dp[i][j] = max(dp[i][k] + dp[k][j] + newNums[i]*newNums[k]*newNums[j])(k∈i+1~j-1)

说明:i到j最小距离为2(j-i >=2)

dp[0][newNums.length-1] 为所求最大coins值。

示例

class Solution {

public int maxCoins(int[] nums) {

// learn from others

int[] newNums = new int[nums.length+2]; //1 nums 1

newNums[0]=1;

newNums[newNums.length-1]=1;

for(int i=0;i

newNums[i+1]=nums[i];

}

int[][] dp = new int[newNums.length][newNums.length];

for(int interval=2; interval

// interval 2: 0~2 1~3 2~4 3~5

// interval 3: 0~3 1~4 2~5

// interval 4: 0~4 1~5

// interval 5: 0~5

for(int start=0; start

for(int index = start+1; index < start +interval; index++){ // index is the iter between start and start+interval

dp[start][start+interval] = Math.max(dp[start][start+interval],

dp[start][index]+dp[index][start+interval]+newNums[start]*newNums[index]*newNums[start+interval]);

}

}

}

return dp[0][newNums.length-1];

}

}

变形

现在说说那道变形的题目吧,阿里的一个编程测验题。

打靶:

在某射击场有N个靶,每个靶上都有一个分数,存在score数组中。击中第i个靶的得分为score[left] * score[i] * score[right],同时原left和right两个靶变为相邻的靶。其中得分为0的靶是不能射击的,当left不存在或者不能射击时,得分为 score[i] * score[right],同理right也遵循此规则; 当left和right都不存在或者不能射击时,得分为score[i]。请计算出击中所有能射击的靶,最多能得多少分?设计算法。

一种思路是:将数组按0分组,每一组用上面的方面计算分值,各组最大分值和就是我们要求的总得分。

Scanner sc = new Scanner(System.in);

int n = sc.nextInt(); // 数组长度

int[] scores = new int[n];

int sum =0;

int len =0;

for(int i=0;i

int temp = sc.nextInt();

if(temp ==0){

sum += maxScore(len, scores);

len =0;

scores = new int[n];

}

else{

scores[len++]=temp;

}

}

这样的输入的话,相应的maxScore()函数在长度,返回值方面要做一些改动,比如 len 为0时,直接返回0就好了。数组头尾加1的操作也要在len的基础上,而不是scores.length。这个还未经验证,不知道是否可行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值