POJ 2248解题报告
2012-12-01 21:18
337 查看
这道题就是个简单的深搜题,不过需要剪枝。
首先addition chains在求幂的时候用到。比如a^15=a*a^14=a*(a^7)^2=a*(a^6*a)^2=...
所以至少有如下一种分解方法:如果n是奇数,分解(n-1);如果n是偶数,分解(n/2)。
这种分解方法可以作为初始上界。之后每次求得一个比这个值小的解时候,更新上界。
其次,避免过多的重复计算。新求出一个数之后,只需要判断这个数和它之前的数的组合(包括它自己),而不需考虑前面的两两组合(因为之前已经求过了)。
代码如下:
首先addition chains在求幂的时候用到。比如a^15=a*a^14=a*(a^7)^2=a*(a^6*a)^2=...
所以至少有如下一种分解方法:如果n是奇数,分解(n-1);如果n是偶数,分解(n/2)。
这种分解方法可以作为初始上界。之后每次求得一个比这个值小的解时候,更新上界。
其次,避免过多的重复计算。新求出一个数之后,只需要判断这个数和它之前的数的组合(包括它自己),而不需考虑前面的两两组合(因为之前已经求过了)。
代码如下:
#include <iostream> using namespace std; void additionchain(int intermids[], int len, int n, int &limit, int res[]) { if(len >= limit) return; for(int i = len - 1; i >= 0; --i) { intermids[len] = intermids[len - 1] + intermids[i]; if(intermids[len] == n) { if(len + 1 <= limit) { limit = len + 1; for(int i = 0; i <= len; ++i) { res[i] = intermids[i]; } } return; } if(intermids[len] < n) { additionchain(intermids, len + 1, n, limit, res); } } } int main() { int n; int intermids[100]; int res[100]; int len = 0; while(true) { cin>>n; if(n == 0) break; else if(n == 1) cout<<"1"<<endl; else if(n == 2) cout<<"1 2"<<endl; else { intermids[0] = 1; intermids[1] = 2; len = 2; int limit = 0; int tmp = n; while(tmp) { if(tmp % 2) { tmp--; } else { tmp >>= 1; } limit++; } additionchain(intermids, len, n, limit, res); for(int i = 0; i < limit; ++i) { cout<<res[i]; if(i != limit - 1) cout<<" "; else cout<<endl; } } } return 0; }
相关文章推荐
- poj1741 Tree解题报告
- POJ-1284-Primitive Roots 解题报告
- POJ 3299(湿润指数 简单数学) 解题报告
- POJ 1163 The Triangle 解题报告
- 置换的基础应用(附POJ 3270 Cow Sorting 解题报告)
- POJ 1214 解题报告
- POJ 3580 较复杂的Splay区间维护题解题报告
- poj1002 487-3279 解题报告
- POj 1105解题报告
- POJ 1922 解题报告
- poj解题报告——1970
- POJ 3414 Pots 解题报告
- poj 1046 Color Me Less 解题报告
- poj解题报告——1032
- poj解题报告——1450
- 解题报告: POJ_2955 Brackets DP
- poj解题报告——2975
- POJ 1002解题报告
- POJ_3126Prime Path解题报告
- poj 1068 Parencodings/bnuoj 1187 Parencodings 解题报告