zoukankan      html  css  js  c++  java
  • HDU 1028 Ignatius and the Princess III 整数的划分问题(打表或者记忆化搜索)

    传送门:

    http://acm.hdu.edu.cn/showproblem.php?pid=1028

    Ignatius and the Princess III

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 24967    Accepted Submission(s): 17245


    Problem Description
    "Well, it seems the first problem is too easy. I will let you know how foolish you are later." feng5166 says.

    "The second problem is, given an positive integer N, we define an equation like this:
      N=a[1]+a[2]+a[3]+...+a[m];
      a[i]>0,1<=m<=N;
    My question is how many different equations you can find for a given N.
    For example, assume N is 4, we can find:
      4 = 4;
      4 = 3 + 1;
      4 = 2 + 2;
      4 = 2 + 1 + 1;
      4 = 1 + 1 + 1 + 1;
    so the result is 5 when N is 4. Note that "4 = 3 + 1" and "4 = 1 + 3" is the same in this problem. Now, you do it!"
     
    Input
    The input contains several test cases. Each test case contains a positive integer N(1<=N<=120) which is mentioned above. The input is terminated by the end of file.
     
    Output
    For each test case, you have to output a line contains an integer P which indicate the different equations you have found.
     
    Sample Input
    4 10 20
     
    Sample Output
    5 42 627
     
    Author
    Ignatius.L
     
    分析:
    整数的划分问题
     关于这个整数划分请参考我的这篇博客
    关于这个题目
    有两种做法
    1.暴力打表
    打表就不是折磨你自己了,而是折磨电脑了
    运行程序之后大概要等几分钟才有结果
    code:
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    #define max_v 125
    /*LL f(int n,int m)
    {
        if(n==1||m==1)
            return 1;
        else if(n==m&&n>1)
        {
            return f(n,n-1)+1;
        }else if(n<m)
        {
            return f(n,n);
        }else if(n>m)
        {
            return f(n,m-1)+f(n-m,m);
        }
    }*/
    int main()
    {
        LL a[]={0,1,2,3,5,7,11,15,22,30,42,56,77,101,135,176,231,297,385,490,627,792,1002,1255,1575,1958,2436,3010,3718,4565,5604,6842,8349,10143,12310,14883,17977,21637,26015,31185,37338,44583,53174,63261,75175,89134,105558,124754,147273,173525,204226,239943,281589,329931,386155,451276,526823,614154,715220,831820,966467,1121505,1300156,1505499,1741630,2012558,2323520,2679689,3087735,3554345,4087968,4697205,5392783,6185689,7089500,8118264,9289091,10619863,12132164,13848650,15796476,18004327,20506255,23338469,26543660,30167357,34262962,38887673,44108109,49995925,56634173,64112359,72533807,82010177,92669720,104651419,118114304,133230930,150198136,169229875,190569292,214481126,241265379,271248950,304801365,342325709,384276336,431149389,483502844,541946240,607163746,679903203,761002156,851376628,952050665,1064144451,1188908248,1327710076,1482074143,1653668665,1844349560,2056148051,2291320912,2552338241,2841940500};
        /*for(int i=1;i<max_v;i++)
        {
            printf("%I64d,",f(i,i));
        }
        printf("
    **
    ");*/
        int n;
        while(~scanf("%d",&n))
        {
            printf("%I64d
    ",a[n]);
           // printf("%I64d
    ",f(n,n));
        }
        return 0;
    }

    2.另外一种做法

    记忆化搜索

    就是在搜索之前先判断一下,搜过了就不再搜索了

    跟dp一个意思

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    #define max_v 125
    int dp[max_v][max_v];
    LL f(int n,int m)
    {
        if(dp[n][m]!=-1)//判断有没有搜过
            return dp[n][m];
        if(n==1||m==1)
            return dp[n][m]=1;
        else if(n==m&&n>1)
        {
            return dp[n][m]=f(n,n-1)+1;
        }else if(n<m)
        {
            return dp[n][m]=f(n,n);
        }else if(n>m)
        {
            return dp[n][m]=f(n,m-1)+f(n-m,m);
        }
    }
    int main()
    {
        //两种做法
        //LL a[]={0,1,2,3,5,7,11,15,22,30,42,56,77,101,135,176,231,297,385,490,627,792,1002,1255,1575,1958,2436,3010,3718,4565,5604,6842,8349,10143,12310,14883,17977,21637,26015,31185,37338,44583,53174,63261,75175,89134,105558,124754,147273,173525,204226,239943,281589,329931,386155,451276,526823,614154,715220,831820,966467,1121505,1300156,1505499,1741630,2012558,2323520,2679689,3087735,3554345,4087968,4697205,5392783,6185689,7089500,8118264,9289091,10619863,12132164,13848650,15796476,18004327,20506255,23338469,26543660,30167357,34262962,38887673,44108109,49995925,56634173,64112359,72533807,82010177,92669720,104651419,118114304,133230930,150198136,169229875,190569292,214481126,241265379,271248950,304801365,342325709,384276336,431149389,483502844,541946240,607163746,679903203,761002156,851376628,952050665,1064144451,1188908248,1327710076,1482074143,1653668665,1844349560,2056148051,2291320912,2552338241,2841940500};
        /*for(int i=1;i<max_v;i++)
        {
            printf("%I64d,",f(i,i));
        }
        printf("
    **
    ");*/
        memset(dp,-1,sizeof(dp));//没有搜索的标记
        int n;
        while(~scanf("%d",&n))
        {
            //printf("%I64d
    ",a[n]);
            printf("%I64d
    ",f(n,n));
        }
        return 0;
    }
  • 相关阅读:
    矩阵构造方法(转载)
    欧拉函数
    POJ3233:Matrix Power Series(矩阵快速幂+二分)
    矩阵快速幂(转载)
    素数筛法模板
    快速幂取模算法
    hdu1286(找新朋友)&&POJ2407Relatives(欧拉函数模版题)
    判断两线段相交
    POJ3070:Fibonacci(矩阵快速幂模板题)
    HDU1575:Tr A(矩阵快速幂模板题)
  • 原文地址:https://www.cnblogs.com/yinbiao/p/9314581.html
Copyright © 2011-2022 走看看