首页 > 代码库 > uva 10254
uva 10254
如果我们设f[i]为4个柱子时把i个东东从一个柱子移到另一个柱子所用的最少步骤,设g[i]为3个柱子时对应的值,我们可以得到f[n]=min{2*f[k]+g[n-k]},其中g[i]是已知的为2^i-1。
然后接着就搞不下去了,看了别人报告说要找规律。有了上面的式子之后,我们打印前60个解还是很好打印的,同时把f[i]-f[i-1]也打印出来,这时会发现f[i]-f[i-1]都是2的某次方,而且2的k次方一共连续出现了k+1次,于是我们就可以以这个特征为依据预处理出所有解了
#include <iostream>#include <cstdio>#include <string.h>#include <algorithm>using namespace std;typedef long long ll;const int mod=100000000;struct Bignumber{ int V[50]; int len; void clear(){ memset(V,0,sizeof(V)); len=1; } Bignumber operator *( int od){ Bignumber ans; ans.clear(); for(int i=0; i<len; ++i){ ans.V[i]+=V[i]*od; ans.V[i+1]+=(ans.V[i])/mod; ans.V[i]%=mod; } ans.len=len; while(ans.V[ans.len]>0){ ans.V[ans.len+1]+=ans.V[ans.len]/mod; ans.V[ans.len]%=mod; ans.len++; } return ans; } Bignumber operator +( Bignumber od){ Bignumber ans; ans.clear(); int L=max(len,od.len); for(int i=0; i<L; ++i){ ans.V[i]+=V[i]+od.V[i]; ans.V[i+1]+=ans.V[i]/mod; ans.V[i]%=mod; } ans.len=L; while(ans.V[ans.len]>0){ ans.V[ans.len+1]+=ans.V[ans.len]/mod; ans.V[ans.len]%=mod; ans.len++; } return ans; } void print(){ printf("%d",V[len-1]); for(int i=len-2; i>=0; --i){ printf("%08d",V[i]); } // printf("\n"); }}F[10002];ll dp[65];ll f[65];int main(){ Bignumber t; t.V[0]=1; t.len=1; F[0].clear(); int num=1,loc=1; while(loc<=10000){ for(int i=0; i<num&&loc<=10000; ++i){ F[loc]=F[loc-1]+t; loc++; } num++; t=t*2; // t.print(); printf("\n"); } int n; while(scanf("%d",&n)==1){ F[n].print(); printf("\n"); } return 0;}
uva 10254
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。