1. 程式人生 > >UVA1374-Power Calculus(叠代加深搜索)

UVA1374-Power Calculus(叠代加深搜索)

tar 叠代加深搜索 inf tip 題目 leading art program i++

Problem UVA1374-Power Calculus

Accept:323 Submit:2083

Time Limit: 3000 mSec

技術分享圖片 Problem Description

技術分享圖片

技術分享圖片 Input

The input is a sequence of one or more lines each containing a single integer n. n is positive and less than or equal to 1000. The end of the input is indicated by a zero.

技術分享圖片 Output

Your program should print the least total number of multiplications and divisions required to compute xn starting with x for the integer n. The numbers should be written each in a separate line without any super?uous characters such as leading or trailing spaces.

技術分享圖片 Sample Input

1 31 70 91 473 512 811 953 0

技術分享圖片 Sample Ouput

0
6
8
9
11
9
13
12

題解:IDA*算法,思路很直接,剪枝也很明顯,就是如果目前最大的數,在接下來的幾輪叠代中如果每次都翻倍還到不了n就剪枝。

還有一個神奇的剪枝就是每次都要利用到最後生成的那個數(不知道為啥)。

我一開始使用set進行集合操作,但是多了個log就讓效率崩了,13層的就很難輸出了,看了lrj的代碼改成數組效率大大提高,以後在註重效率的地方還是盡量少用STL。

這個題讓我比較困惑的是在代碼中如果沒有當 d == maxd 時return false;就會出現神奇的錯誤,而前幾道IDA*的題目在這一點上都不太重要,冥思苦想,大概知道為啥了。

前幾道類似的題目不會出現d超過maxd還能繼續遞歸下去的情況(由估價函數可以清楚看到),但是這個題不一樣,從估價函數中可以看到(見代碼),這樣的情況是完全可能出現的,因此可能這次遞歸開始設置的閾值是10,但是到10沒停下來,繼續深度遞歸,然後返回true導致程序誤以為在這個閾值時正好搜索到結果,輸出錯誤結果,這個點以後一定要註意,或者幹脆每次寫都加上這句,對效率應該不會有大的影響,理解不對的地方請大佬指教。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5
#include <set> 6 7 using namespace std; 8 9 const int maxn = 15; 10 11 int n,maxd; 12 int a[maxn+1]; 13 14 bool dfs(int d) { 15 if (a[d] == n) return true; 16 if (d == maxd) return false; 17 18 int Max = a[0]; 19 for (int i = 0; i <= d; i++) { 20 Max = Max > a[i] ? Max : a[i]; 21 } 22 if ((Max << (maxd - d)) < n) return false; 23 24 for (int i = d; i >= 0; i--) { 25 a[d + 1] = a[d] + a[i]; 26 if (dfs(d + 1)) return true; 27 a[d + 1] = a[d] - a[i]; 28 if (dfs(d + 1)) return true; 29 } 30 return false; 31 } 32 33 int main() 34 { 35 //freopen("input.txt", "r", stdin); 36 while (scanf("%d", &n) == 1 && n) { 37 if (n == 1) { 38 printf("0\n"); 39 continue; 40 } 41 memset(a, 0, sizeof(a)); 42 a[0] = 1; 43 for (maxd = 1;; maxd++) { 44 if(dfs(0)) break; 45 } 46 printf("%d\n", maxd); 47 } 48 return 0; 49 }

UVA1374-Power Calculus(叠代加深搜索)