zoukankan      html  css  js  c++  java
  • codevs 1039 数的划分

      

    题目描述 Description

    将整数n分成k份,且每份不能为空,任意两种划分方案不能相同(不考虑顺序)。
    例如:n=7,k=3,下面三种划分方案被认为是相同的。
    1 1 5

    1 5 1

    5 1 1
    问有多少种不同的分法。

    输入描述 Input Description

    输入:n,k (6<n<=200,2<=k<=6)

    输出描述 Output Description


    输出:一个整数,即不同的分法。

    样例输入 Sample Input

     7 3

    样例输出 Sample Output

    4

    数据范围及提示 Data Size & Hint

     {四种分法为:1,1,5;1,2,4;1,3,3;2,2,3;}

    首先附上枚举所有情况的代码,由于数据比较水,所以可以ac
    #include<cstdio>
    int ans=0;
    void dfs(int a,int b,int c)
    {
        if(!a||!b)
        {
            if(!a&&!b) ++ans;
            return;
        }
        for(int i=c;i<=a;++i)
            dfs(a-i,b-1,i);
    }
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
        dfs(n,k,1);
        printf("%d",ans);
        return 0;
    }

    然后思考如何通过递推解决,直接以上面的程序进行记忆化搜索是不行的,因为我们在统计方案时要保证序列的递增性所以在统计的时候会有一部分无法统计到

    这道题的递推公式是:f[i][j]=f[i-1][j-1]+f[i-j][j];

    这个公式可以通过打表找出来

    实际解释的话我们思考划分的方案只有两种,一种是有1,一种是没有的。

    1.有1的情况,就把1的那份挑出来。

    2.没有1的情况,那么我们就把每一份都先放一个1,这剩余要分的数的和就为i-j了

    #include<cstdio>
    int f[205][10];
    int main()
    {   int n,k;
        scanf("%d%d",&n,&k);
        f[0][0]=1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=k;j++)
                if(i>=j) f[i][j]=f[i-1][j-1]+f[i-j][j];
        printf("%d",f[n][k]);
        return 0;
    } 
  • 相关阅读:
    51 Nod 1086 多重背包问题(单调队列优化)
    51 Nod 1086 多重背包问题(二进制优化)
    51 Nod 1085 01背包问题
    poj 2559 Largest Rectangle(单调栈)
    51 Nod 1089 最长回文子串(Manacher算法)
    51 Nod N的阶乘的长度 (斯特林近似)
    51 Nod 1134 最长递增子序列(经典问题回顾)
    51 Nod 1020 逆序排列
    PCA-主成分分析(Principal components analysis)
    Python中cPickle
  • 原文地址:https://www.cnblogs.com/bzmd/p/9432773.html
Copyright © 2011-2022 走看看