这是昨天在了解动态规划时看到的一道题目。.
题意是这样的:
有一个村子,村子里的房屋围着一口井建的,现在井坏了,要花钱修理,所以在村子里募捐。每户人家都讨厌自己的邻居,只要自己的邻居捐了,那自己就不愿意捐。现在知道每户人家可以捐出的数目,求可以募捐的最大金额是多少?
意思就是在一列数组中取数,相邻的两个数不能够一起被取出,起始点和末尾点也是相邻的(因为是围着一口井建的,可以理解成一个圆),求取出序列的和最大是多少。
输入输出示范:
0)
input:
10
1 2 3 4 5 1 2 3 4 5
Returns: 16
1)
input:
2
21 17
Returns: 21
2)
input:
5
5 5 5 5 5
Returns:10
3)
input:
1051 66 88 77 12 54 94 62 15 36
Returns: 295
输入格式:
第一行输入一个数N 表示村子总户数。
第二排输入N个数,表示每户人家愿意提供的捐款金额。
输出格式:
村子最大募捐和。
import java.util.Scanner;
public class Main {
static int Dptool(int N,int[] num){
int a,b;
//分成两个区间,为了排除起始点和末尾点相邻的情况。
a = Dp(false, N, num);//0-N-1
b = Dp(true, N, num);//1-N
System.out.println(a+"-"+b);
//取a,b中大的值。
if (a >= b)
return a;
else
return b;
}
static int Dp(boolean first,int N,int[] num){
int aflag = 0;
int bflag = num[0];
int end = N;
if (first == false) {//0-N-1
end = N-1;
}else if(first == true){//1-N
bflag = 0;
end = N;
}
for (int i = 1; i < end; i++) {
if (aflag +num[i] >= bflag ) {
int temp = bflag;
bflag = aflag + num[i];
aflag = temp;
}
else {
aflag = bflag;
}
}
return bflag;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int[] num = new int[N];
for (int i = 0; i < N; i++) {
num[i] = sc.nextInt();
}
System.out.println(Dptool(N,num));
}
}
动态规划的要点顾名思义,掌握每次动态变化过程对整体的影响。
动态规划典型例子 - 求最长递增序列长度 LIS:longest increasing subsequence。
本题思路也是如此,每次增加一户人口,判断对最大值的影响,不断的更新最优解。