zoukankan      html  css  js  c++  java
  • HDU 2566 统计硬币 (母函数或dfs)

    统计硬币

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 8202    Accepted Submission(s): 5606


    Problem Description
    假设一堆由1分、2分、5分组成的n个硬币总面值为m分,求一共有多少种可能的组合方式(某种面值的硬币可以数量可以为0)。
     
    Input
    输入数据第一行有一个正整数T,表示有T组测试数据;
    接下来的T行,每行有两个数n,m,n和m的含义同上。
     
    Output
    对于每组测试数据,请输出可能的组合方式数;
    每组输出占一行。
     
    Sample Input
    2 3 5 4 8
     
    Sample Output
    1 2
     
    Author
    lemon
     
    Source
     
    Recommend
    yifenfei   |   We have carefully selected several similar problems for you:  2561 2562 2152 2564 2082 
     
    分析:可以用二维的母函数来记录一下数量,也可以用DFS
     
    母函数:
    #include<iostream>
    #include <cstring>
    using namespace std;
    #define M 1000   //M为(x的最大指数+1)
    #define MAXN 130      //MAXN为最大有多少项相乘
    int a[M][150],b[M][150];//a[M]中存最终项系数;b[M]中存取中间变量;
    int main()
    {
        int m,n;
        int i,j,k,r;
        m=MAXN;
        int t;
        scanf("%d",&t);
        while(t--){
           scanf("%d%d",&r,&n);
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            //n为所求的指数的值: ";
            //因为只求指数为n的系数的值:所以循环只到n就结束
            for(i=0;i<=n;i++)//初始化第一个式子:(1+X+X^2+X^3+...) 所以将其系数分别存到a[n]
            {
                a[i][i]=1;
            }
            for(i=2;i<=5;i=i+3)//从第2项式子一直到第n项式子与原来累乘项的和继续相乘
            {
                for(j=0;j<=n;j++)//从所累乘得到的式子中指数为0遍历到指数为n 分别与第i个多项式的每一项相乘
                     for(k=0;k+j<=n&&k/i<=r;k+=i)//第i个多项式的指数从0开始,后面的每项指数依次比前面的多i,比如当i=3时,第3项的表达式为(1+x^3+x^6+x^9+……),直到所得指数的值i+j>=n退出
                     {
                         for(int z=0;z+k/i<=r;z++){
                         b[j+k][z+k/i]+=a[j][z];
                         }//比如前面指数为1,系数为3,即a[1]=3 的一项和下一个表达式的指数为k=3的相乘,则得到的式子的系数为,b[j+k]=b[4]+=a[1],又a[1]=3,所以指数为4的系数为b[4]=3;
                     }
                 for(j=0;j<=n;j++)//  然后将中间变量b数组中的值依次赋给数组a,然后将数组b清零,继续接收乘以下一个表达式所得的值
                  {
                     for(int k=0;k<=r;k++){
                      a[j][k]=b[j][k];
                      b[j][k]=0;
                     }
                  }
            }
            printf("%d
    ",a[n][r]);  // 指数为n的项的系数为:
        }
        return 0;
    }

    DFS:

    #include <iostream>
    #include  <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int n,m,ans;
    void dfs(int x,int sum,int step)
    {
        if(sum>m)return;
        if(sum==m&&step==n)
        {
        ans++;
        return;
        }
        if(step==n)
        return;
       if(x==5)
       {
    
        dfs(5,sum+5,step+1);
       }
       else if(x==1)
       {
         dfs(1,sum+1,step+1);
        dfs(2,sum+2,step+1);
        dfs(5,sum+5,step+1);
       }
       else if(x==2)
       {
       dfs(2,sum+2,step+1);
        dfs(5,sum+5,step+1);
       }
    }
    int main()
    {
        int t;
       scanf("%d",&t);
       while(t--)
       {
           ans=0;
           scanf("%d%d",&n,&m);
           dfs(1,1,1);
           dfs(2,2,1);
           dfs(5,5,1);
           printf("%d
    ",ans);
       }
    return 0;
    }
     
  • 相关阅读:
    使用SolrJ生成索引
    olr 性能调优 NO_NORMS
    关于 solr solrconfig.xml 的配置说明
    动态生成二维码并利用canvas合成出一张图片(类似海报、分享页)
    如何将打包好的文件做成一个APP
    vue路由对不同界面进行传参及跳转的总结
    移动端自适应布局的适配
    08年12月到1月15的工作
    继续被reject!
    虽然预料到结果,但还是感觉不爽!
  • 原文地址:https://www.cnblogs.com/a249189046/p/7550752.html
Copyright © 2011-2022 走看看