找数游戏
Description
小明有一个整数数组nums,他希望找出并返回能被三整除的元素最大和。你能找出符合要求的数。
Input
输入整数数组nums的各个元素,数字间用","相隔。
1≤nums.length≤10
1≤nums[i]≤10^4
Output
输出能被3整除的元素最大和,无符合要求的元素则输出0。
Sample
代码
java
import java.util.ArrayList;
import java.util.Scanner;
import static java.lang.Math.max;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
ArrayList<Integer> arrayList = new ArrayList<>();
int a = 0;
String[] s = in.nextLine().split(",");
for(int i = 0;i<s.length;i++){
arrayList.add(Integer.parseInt(s[i]));
}
System.out.println(maxSumDivThree(arrayList));
}
public static int maxSumDivThree(ArrayList<Integer> nums) {
int n = nums.size();
int dp[][] = new int[n+2][3];
dp[0][0] = 0; dp[0][1] = Integer.MIN_VALUE; dp[0][2] = Integer.MIN_VALUE;
for(int i = 1;i <= n;i++)
{
int t = nums.get(i-1)%3;
if(t == 0)
{
dp[i][0] = max(dp[i-1][0], dp[i-1][0] + nums.get(i-1));
dp[i][1] = max(dp[i-1][1], dp[i-1][1] + nums.get(i-1));
dp[i][2] = max(dp[i-1][2], dp[i-1][2] + nums.get(i-1));
}
else if(t == 1)
{
dp[i][0] = max(dp[i-1][0], dp[i-1][2] + nums.get(i-1));
dp[i][1] = max(dp[i-1][1], dp[i-1][0] + nums.get(i-1));
dp[i][2] = max(dp[i-1][2], dp[i-1][1] + nums.get(i-1));
}
else if(t == 2)
{
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + nums.get(i-1));
dp[i][1] = max(dp[i-1][1], dp[i-1][2] + nums.get(i-1));
dp[i][2] = max(dp[i-1][2], dp[i-1][0] + nums.get(i-1));
}
}
return dp[n][0];
}
}
思路
使用动态规划解决
状态转移方程:
dp[i][j] = max(dp[i-1][j], dp[i-1][3-j] + nums.get(i-1)); ( * 根据情况而定)
比如 t%3 == 2
对于dp[i][0],有前两种状态可以递推得到:
dp[i-1][1] + t
dp[i-1][0]
从这两种状态中取最大值,就是前 i 个数中%3==0的最大和。
我们也需要保证dp[i-1][1]是最大的,因此我们要写3个dp,并且要分类讨论。