POJ 2248解题报告

来源:互联网 发布:java一致性哈希算法 编辑:程序博客网 时间:2024/05/13 07:26

这道题就是个简单的深搜题,不过需要剪枝。


首先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<<" ";elsecout<<endl;}}}return 0;}


原创粉丝点击