zoukankan      html  css  js  c++  java
  • 《训练指南》——6.9

    Uva11137

      立方体之和:输入正整数n(n10000),求将n写成若干个正整数的立方体之和有多少种方法。

      分析:这道题目其实就是基于递推的一道动态规划题目了,我们建立记录多状态的多段图,利用d[i][j]来表示立方数的底数不超过i且最终和为j的方法数,结合n的取值,有21^3 > 10000,因此这里的最终答案便是d[21][n].

      下面我们面临的问题就是如何求解d[i][j],即寻求递推关系。对于d[i][j],我们分成如下的两种情况:

    (i)和式当中最大的底数是i-1,则有d[i-1][j]种情况。

    (ii)和式当中最大的底数是i,则有d[i][j-i^3]种情况。

    可以看到,d[i][j]基于的子状态两个维度的参数都小于或等于ij,这放在动态规划当中,叫做无后效性。

     #include<cstdio>
    
    #include<cstring>
    
    using namespace std;
    
     
    
    int main()
    
    {
    
     
    
         long long d[23][10005];
    
         memset(d , 0 , sizeof(d));
    
           d[0][0] = 1;
    
         for(int i = 1;i < 23;i++)
    
              for(int j = 0;j < 10005;j++)
    
                {
    
                if(j-i*i*i >= 0)
    
                   d[i][j] = d[i-1][j] + d[i][j-i*i*i];
    
                else
    
                   d[i][j] = d[i-1][j];
    
                }
    
     
    
               // printf("%d
    ",d[1][0]);
    
     
    
        int n;
    
        while(scanf("%d",&n) != EOF)
    
        {
    
             printf("%lld
    ",d[22][n]);
    
        }
    
     
    
    }

    Uva11375(需要高精度,还没有A)

      火柴:用n(1n2000)根能够组成多少个非负整数?

      分析:我们设置d[i]恰好用i根火柴摆出不同的非负整数的个数。F[n]是本题结果,则显然有F[n] = d[i]。因此现在我们面临的问题是如何计算d[n]

      我们用c[x]记录拼出个位数x所需要的火柴数目,那么现在考察d[n]中的所有情况,为了便于找到递推关系,我们都去掉每一个整数的个位,这样我们能够找到如下的状态转移方程,或者说是递推方程:

      d[n] = d[n-c[i]],i[0,9].

      但是在编码实现的时候,并不是线性得求出d[1],d[2]…d[n],而是动态的更新d[1]d[2]…的值,从状态转移方程中能够看出,d[n]需要基于更小规模的子问题d[n-c[i]],因此这里我们首先设置一层循环遍历1~n作为d[]下标的参数,然后再进行“添加尾数”的操作,这样就有如下的状态转移方程:

      for i 0 to maxn

    for j 0 to 9

      d[i+c[j]] += d[i]

    简单的参考代码如下(Ps原题结果较大应用高精度运算)

    #include<cstdio>
    
    #include<cstring>
    
    using namespace std;
    
    const int maxn = 2005;
    
    int main()
    
    {
    
        int c[10] = {6,2,5,5,4,5,6,3,7,6};
    
        int d[maxn];
    
        memset(d , 0 , sizeof(d));
    
        d[0] = 1;
    
        for(int i = 0;i < maxn;i++)
    
              for(int j = 0;j < 10;j++)
    
                 if(!(i==0 && j==0) && i + c[j] < maxn)
    
                  d[i+c[j]] += d[i];
    
        int n;
    
           
    
        while(scanf("%d",&n) != EOF)
    
        {
    
              int sum = 0;
    
              for(int i = 1;i <= n;i++)
    
                   sum += d[i];
    
            printf("%d
    ",sum);
    
        }
    
     
    
       // printf("%d %d %d %d",d[2],d[3],d[4],d[5]);
    
    }
  • 相关阅读:
    高级(线性)素数筛
    Dijkstra(迪杰斯特拉)算法
    简单素数筛
    【解题报告】 POJ1958 奇怪的汉诺塔(Strange Tower of Hanoi)
    4 jQuery Chatting Plugins | jQuery UI Chatbox Plugin Examples Like Facebook, Gmail
    Web User Control Collection data is not storing
    How to turn on IE9 Compatibility View programmatically in Javascript
    从Javascrip 脚本中执行.exe 文件
    HtmlEditorExtender Ajax
    GRIDVIEW模板中查找控件的方式JAVASCRIPT
  • 原文地址:https://www.cnblogs.com/rhythmic/p/5576534.html
Copyright © 2011-2022 走看看