https://community.topcoder.com/stat?c=problem_statement&pm=2402&rd=5009
http://www.cnblogs.com/lautsie/p/3250940.html
题目描述:n个数围成一个圆圈,求最大的子集和使得每一个数都不和其他任何数是相邻的。
f[i][0]表示2...i这些数能得到的最大和,f[i][1]表示 1....i-1这些数能得到的最大和。
f[i][0] 和 f[i-1][0] , f[i-2][0]+A[i]有关系, f[i][1] 和 f[i-1][1], f[i-2][0]+A[i]有关系。
计算子问题的顺序:i form 0 to n-1.
https://github.com/mrincodi/Topcoder/blob/master/BadNeighbors.java
public static int maxDonations(int[] donations){
if ( donations == null ) return -1;
if ( donations.length == 1 ) return donations [ 0 ];
if ( donations.length == 2 ) return Math.max(donations [ 0 ], donations [ 1 ]);
//Array S will have best (non consecutive) sum for all values
//Array S1 will have best (non consecutive) sum for all values, except the first one (S1[0]=0) !
int [] S = new int [ donations.length ];
int [] S1 = new int [ donations.length ];
S[0]=donations [ 0 ];
S[1]=donations [ 1 ];
S1[0]=0;
S1[1]=donations [ 1 ];
for ( int i = 2; i < donations.length - 1; i++){
S[i]=Math.max(S[i-1], S[i-2] + donations[i]);
S1[i]=Math.max(S1[i-1], S1[i-2] + donations[i]);
}
//Final value will be the max between
// (for the array that considers all values, best answer until one less the last one) and
// (for the array that considers all values except the first one,
// best answer until two less the final one, plus the final one).
int valorFinal = Math.max(S[donations.length - 2], S1[donations.length - 3] + donations[donations.length - 1]);
return valorFinal;
}
https://github.com/irpap/TopCoder/blob/master/BadNeighbors/src/BadNeighbors.java
The old song declares "Go ahead and hate your neighbor", and the residents of Onetinville have taken those words to heart. Every resident hates his next-door neighbors on both sides. Nobody is willing to live farther away from the town's well than his neighbors, so the town has been arranged in a big circle around the well. Unfortunately, the town's well is in disrepair and needs to be restored. You have been hired to collect donations for the Save Our Well fund.
Each of the town's residents is willing to donate a certain amount, as specified in the int[] donations, which is listed in clockwise order around the well. However, nobody is willing to contribute to a fund to which his neighbor has also contributed. Next-door neighbors are always listed consecutively in donations, except that the first and last entries in donations are also for next-door neighbors. You must calculate and return the maximum amount of donations that can be collected.
| |||||||||||||
Definition | |||||||||||||
| |||||||||||||
Constraints | |||||||||||||
- | donations contains between 2 and 40 elements, inclusive. | ||||||||||||
- | Each element in donations is between 1 and 1000, inclusive. | ||||||||||||
Examples | |||||||||||||
0) | |||||||||||||
|
题目描述:n个数围成一个圆圈,求最大的子集和使得每一个数都不和其他任何数是相邻的。
f[i][0]表示2...i这些数能得到的最大和,f[i][1]表示 1....i-1这些数能得到的最大和。
f[i][0] 和 f[i-1][0] , f[i-2][0]+A[i]有关系, f[i][1] 和 f[i-1][1], f[i-2][0]+A[i]有关系。
计算子问题的顺序:i form 0 to n-1.
public
int
maxDonations(
int
[] donations) {
int
len = donations.length;
if
(len ==
0
)
return
0
;
if
(len ==
1
)
return
donations[
0
];
if
(len ==
2
)
return
Math.max(donations[
0
], donations[
1
]);
int
[][] matrix =
new
int
[len][
2
];
// len >= 3
// [i][0] means max from 0..i-1
// [i][1] means max from 1..i
matrix[
1
][
0
] = donations[
0
];
matrix[
1
][
1
] = donations[
1
];
matrix[
2
][
0
] = Math.max(donations[
0
], donations[
1
]);
matrix[
2
][
1
] = Math.max(donations[
1
], donations[
2
]);
for
(
int
i =
3
; i < donations.length; i++) {
matrix[i][
0
] = Math.max(matrix[i-
1
][
0
], matrix[i-
2
][
0
] + donations[i-
1
]);
matrix[i][
1
] = Math.max(matrix[i-
1
][
1
], matrix[i-
2
][
1
] + donations[i]);
}
return
Math.max(matrix[len-
1
][
0
], matrix[len-
1
][
1
]);
}
public static int maxDonations(int[] donations){
if ( donations == null ) return -1;
if ( donations.length == 1 ) return donations [ 0 ];
if ( donations.length == 2 ) return Math.max(donations [ 0 ], donations [ 1 ]);
//Array S will have best (non consecutive) sum for all values
//Array S1 will have best (non consecutive) sum for all values, except the first one (S1[0]=0) !
int [] S = new int [ donations.length ];
int [] S1 = new int [ donations.length ];
S[0]=donations [ 0 ];
S[1]=donations [ 1 ];
S1[0]=0;
S1[1]=donations [ 1 ];
for ( int i = 2; i < donations.length - 1; i++){
S[i]=Math.max(S[i-1], S[i-2] + donations[i]);
S1[i]=Math.max(S1[i-1], S1[i-2] + donations[i]);
}
//Final value will be the max between
// (for the array that considers all values, best answer until one less the last one) and
// (for the array that considers all values except the first one,
// best answer until two less the final one, plus the final one).
int valorFinal = Math.max(S[donations.length - 2], S1[donations.length - 3] + donations[donations.length - 1]);
return valorFinal;
}
https://github.com/irpap/TopCoder/blob/master/BadNeighbors/src/BadNeighbors.java