• 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("
    ");
         }
    }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("
    ");
        }
        int n;
        while(scanf("%d",&n)==1){
             F[n].print();
             printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【CSS 第五天】背景,边框
    CSS Sprite雪碧图
    【ASP】session实现购物车
    【ASP】response和sever对象实现用户登录
    【操作系统】银行家算法
    【操作系统】先来先服务
    【操作系统】多级反馈队列算法
    【页面置换算法】LRC算法和FIFS算法
    Alpha版(内部测试版)发布
    项目结束--事后诸葛亮会议总结
  • 原文地址:https://www.cnblogs.com/Opaser/p/4081052.html
Copyright © 2020-2023  润新知