![](/img/trans.png)
[英]Why doesn't my program find the 10001st prime? [Project euler-problem7]
[英]Why doesn't my search algorithm work for Project Euler 31?
問題31
在英格蘭,貨幣由英鎊,英鎊和便士,p組成,並且有八種普通流通硬幣:1p,2p,5p,10p,20p,50p,1英鎊(100p)和2英鎊(200p)。 可以通過以下方式制作£2:1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p使用任意數量的硬幣可以制作多少種不同的£2方式?
static int[] nums = {200,100,50,20,10,5,2,1};
static int size = nums.length;
static HashMap<Integer,Integer> pivots = new HashMap<>();
public static int checkSum(HashMap<Integer,Integer> pivots){
int target = 200;
int sum = 0;
for(Integer key: pivots.keySet()){
int pivot = pivots.get(key);
sum += nums[pivot];
if(sum > target) return 1;
}
if(sum < target) return -1;
return 0;
}
public static void shift(HashMap<Integer,Integer> pivots, int pivot_node){
if(pivots.size() + nums[pivots.get(1)] == 201 && pivots.get(1) != 0){
int p_1_value = pivots.get(1); //this part checks whether the current node(which is the first node)
//has reached children of all 1.
//Which means it's time to shift the root node.
pivots.clear();
pivots.put(1 , p_1_value);
shift(pivots, 1);
return;
}
if(pivots.get(pivot_node) != size - 1) {
pivots.put(pivot_node, pivots.get(pivot_node) + 1);
}
else{
shift(pivots , pivot_node - 1);
}
}
public static void branch(HashMap<Integer,Integer> pivots){
pivots.put(pivots.size() + 1, pivots.get(pivots.size()));
}
public static int search(){
int bool = checkSum(pivots);
int n = 0;
int count = 0;
while(n < 25) {
count++;
if (bool == 0) {
n++; // if the sum is equal to 200, we shift the last
//pivot to the next lower number.
shift(pivots, pivots.size());
}else if (bool == -1) {
branch(pivots); //if the sum is less than 200, we make a new pivot with value of the last pivot.
}else if (bool == 1) {
shift(pivots, pivots.size()); //if the sum is greater than 200,
//we shift to the last pivot to the next lower number.
}
bool = checkSum(pivots);
}
return n;
}
public static void main(String[] args){
pivots.put(1,0);
int n = search();
System.out.print("\n\n------------\n\n"+ "n: " + n);
}
這是一種算法,用於搜索與目標加在一起的集合的組合。 有點像不使用樹的深度優先樹搜索。 每個樞軸代表“樹”上的節點。 shift()方法將節點的值更改為下一個較低的值。 branch()方法創建一個與最后一個節點具有相同值的新節點。 checkSum()方法檢查樞軸的總和是否為目標200。
正確的答案應該在73000左右。但是我的算法僅返回300左右。 我不知道為什么會這樣,因為我的算法應該達到等於200的每個可能組合。
這是我的算法工作方式的可視化:
您的搜索算法無法找到組成£2的硬幣的所有可能組合,因為您只需要將“最后一個樞軸”移動到下一個較低的數字,而您也應該考慮在最后一個之前的項目。
您的算法將找到以下組合:
100、50、20、20、5、2、2、1
但不是這個:
100,20,20,20,10,5,2,2,1
第二個組合中沒有值50,但是您的算法僅將硬幣值從后向后分解為正數-即,直到以下所有“樞軸”都為1時,它才不會分解為50。每當計數器n遞增時HashMap<Integer,Integer> pivots
您的HashMap<Integer,Integer> pivots
。
您可以嘗試通過不僅使用最后一個樞軸,而且還使用所有不同的先前樞軸來shift()
其修改為shift()
來修復代碼。 但是,這樣做會創建很多重復項,因此需要保留找到的不同組合的列表。
解決問題31的另一種方法是使用動態編程。 當涉及到可以分解成較小部分的問題時,動態編程是最好的。 例如,相同問題的解決方案,但target = 2
可以用於解決target = 5
的問題,可以用於解決target = 10
的問題,依此類推。
祝好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.