2 回答

TA貢獻1757條經(jīng)驗 獲得超7個贊
您應該從任何位置獲取所有可能的數(shù)字。因此,為了獲得所有可能的結果,您可以使用這些數(shù)字的排列來序列化這些數(shù)字。另一種方法是使用帶遞歸的位掩碼。這是您的問題的解決方案。(基于位掩碼和遞歸)。
public static boolean isValidResult(ArrayList<Integer> score, int selectedPoints)
{
return canMakeValid(score, selectedPoints, 0, 0); // first 0 is for masking, second 0 is for summation.
}
public static boolean canMakeValid(ArrayList<Integer> score, int selectedPoints, int mask, int sum)
{
if(sum > selectedPoints) return false;
sum %= selectedPoints;
int sz = score.size();
if(mask == ((1<<sz)-1)) {
if(sum == 0) return true;
return false;
}
boolean ret = false;
for(int i = 0; i < sz; i++) {
if((mask&(1<<i)) == 0) {
ret = ret | canMakeValid(score, selectedPoints, mask | (1<<i), sum + score.get(i));
}
}
return ret;
}
您可以從此鏈接了解位掩碼:https://discuss.codechef.com/t/a-small-tutorial-on-bitmasking/11811/3

TA貢獻1827條經(jīng)驗 獲得超8個贊
確實有一些遞歸解決方案。
public static boolean isValidResult(List<Integer> score, int selectedPoints) {
score.sort();
return isValidResultRec(score, selectedPoints, 0);
}
/**
* @param scoreI the first position to consider to add or not add.
*/
private static boolean isValidResultRec(List<Integer> score, int selectedPoints, int scoreI) {
while (!score.isEmpty() && scoreI < score.size()) {
int index = Collections.binarySearch(score, selectedPoints);
if (index >= 0) {
return true;
}
// Now ~index is the insert position;
// i >= ~index are values > selectedPoints.
score = score.subList(~index, score.size());
for (int i = scoreI; i < ~index; ++i) {
int value = score[i]; // value < selectedPoints.
score.remove(i); // Do step.
if (isValidResultRec(score, selectedPoints - value, scoreI + 1) {
return true;
}
score.add(i, value); // Undo step.
}
}
return false;
}
這里使用排序;使用遞減順序、Comparator.reversed()或 afor --i將采取更大的步驟。
遞歸應該添加或不添加第 i個骰子值。
這里的代碼可以寫得更好。
添加回答
舉報