准备考试复习历年题的时候看到CSDN上有很多关于这道题的转载和点评,发现其中大多数JAVA解法采用了同一种方法。这种方法基本上达到了题目要求,但依然无法满足100%通过率。
题目大意:在一个桌子上放了若干个数值不等的红包,围成一个圈,现在让你选取若干个红包,要求相邻的两个红包不能同时选取,编程求出选取红包所得钱数的最大值;
输入:
2
1,2,3
1,2,3,4
输出:
3
6
理解题意后可以得出这其实是强盗问题的环形版(参考地址: https://leetcode.com/problems/house-robber-ii/)
和队列版的区别在于头尾的处理,故分别讨论一下从第0位计算和从第一位计算的区别即可,下面是代码(写的时候比较晚了其实可以对讨论部分做一个函数优化的):
package code_test;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class HongBao {
//构造输入
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = Integer.valueOf(in.nextLine());
//list作为主要存储
List<int[]> list = new ArrayList<int[]>();
for(int i = 0; i < n; i++){
String[] temp = in.nextLine().split(",");
int[] arr = new int[temp.length];
for(int j = 0; j < temp.length; j++){
arr[j] = Integer.valueOf(temp[j]);
}
list.add(arr);
}
for(int[] l:list){
//特例长度为1时
if(l.length==1)
{
System.out.println(l[0]);
}else{
//分组讨论
int include = 0;
int exclude = 0;
for(int i=0;i<l.length-1;i++)
{
int x1 = include;
int y1 = exclude;
include = y1+l[i];
exclude = Math.max(y1, x1);
}
int com = Math.max(include, exclude);
int include1 = 0;
int exclude1 = 0;
for(int j=1;j<l.length;j++)
{
int x2 = include1;
int y2 = exclude1;
include1 = y2+l[j];
exclude1 = Math.max(y2, x2);
}
//取最优结果
com = Math.max(Math.max(include1,exclude1), com);
//输出
System.out.println(com);
}
}
}
}
测试输入为1,100,2,3,110,4,5,111时与简单版答案有出入,简单版为218,正确的应该是321