UVA529 Addition Chains
阿新 • • 發佈:2018-11-26
當前 應該 while tdi ++i ida cpp getchar() char
嘟嘟嘟
還是\(IDA*\)。
這道題是\(ZOJ\)的加強版,\(n\)從\(100\)擴大到了\(10000\),所以必須有非常給力的剪枝才能過。
除了叠代加深,還要加上估價函數:對於當前數\(x\),\(h(x)\)應該是\(O(\log_{2}{x})\),即每一次否給\(x\)乘\(2\)。
然後如果這麽手動取乘\(2\)的話,註意得開\(long \ \ long\),要不然會出現負數而\(T\)飛的……
#include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<cstdlib> #include<cctype> #include<vector> #include<stack> #include<queue> using namespace std; #define enter puts("") #define space putchar(‘ ‘) #define Mem(a, x) memset(a, x, sizeof(a)) #define rg register typedef long long ll; typedef double db; const int INF = 0x3f3f3f3f; const db eps = 1e-8; const int maxn = 1e4 + 5; inline ll read() { ll ans = 0; char ch = getchar(), last = ‘ ‘; while(!isdigit(ch)) last = ch, ch = getchar(); while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - ‘0‘, ch = getchar(); if(last == ‘-‘) ans = -ans; return ans; } inline void write(ll x) { if(x < 0) x = -x, putchar(‘-‘); if(x >= 10) write(x / 10); putchar(x % 10 + ‘0‘); } int n, dep = 0, a[100]; bool dfs(int step) { if(step == dep) return a[step] == n ? 1 : 0; for(int i = 0; i <= step; ++i) for(int j = i; j <= step; ++j) { if(a[i] + a[j] > n || a[i] + a[j] <= a[step]) continue; ll sum = a[i] + a[j]; for(int k = step + 2; k <= dep; ++k) sum <<= 1; if(sum < n) continue; a[step + 1] = a[i] + a[j]; if(dfs(step + 1)) return 1; } return 0; } int main() { while(scanf("%d", &n) && n) { Mem(a, 0); a[0] = 1; int tp = n; dep = 0; while(tp >>= 1) dep++; for(; !dfs(0); dep++); write(a[0]); for(int i = 1; i <= dep; ++i) space, write(a[i]); enter; } return 0; }
UVA529 Addition Chains