• 数的划分


    D14438. 【NOIP2001T】数的划分

    时间限制1.0s   内存限制256.0MB  

    输入文件名:div.in   输出文件名:div.out

    试题来源:NOIP

    问题描述

      将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。

      例如:n=7,k=3,下面三种分法被认为是相同的。

      1,1,5; 1,5,1; 5,1,1;

      问有多少种不同的分法。

    输入格式

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

    输出格式

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

    样例输入

    7 3

    样例输出

    4

    思路:

    先努力尝试递归。

    用n个数分成k份时

    情况一:在第k份放下1份数,为了前k-1份都>1 ,前k-1份都+1,f(n,k)=f(n-k,k);

    情况二:前k-1份中已有1,剩下n-1数,k-1份,f(n,k)= f(n-1,k-1);

    如若数字小于份数自然分不下去了,相等时自然只有一种方法,k=1时也只有一种。

    综上

    f(n,k)= f(n-1,k-1) +f(n-k,k)

            1 (k=1||n=k&&n!=0)

            0 (n<k)

     

    Code

    递归:

    #include<bits/stdc++.h>
    
     
    
    using namespace std;
    
     
    
    int n,k;
    
     
    
    int dive(int num, int p){
    
                   if (num < p) return 0;
    
                   if ((num == p && num != 0) || p == 1) return 1;//边界
    
                   return dive(num - 1, p - 1) + dive(num - p, p);
    
    }
    
     
    
    int main(){
    
                   freopen("div.in","r",stdin);
    
                   freopen("div.out","w",stdout);
    
                   cin >> n >> k;
    
                   int ans = dive(n,k);
    
                   cout << ans << endl;
    
                   return 0;
    
    }

    记忆化:

    #include<bits/stdc++.h>
    
     
    
    using namespace std;
    
     
    
    int n,k;
    
    int dp[210][10];
    
     
    
    int dive(int num, int p){
    
                   if (num < p) return 0;
    
                   if ((num == p && num != 0) || p == 1) return 1;//边界
    
                   if (dp[num][p]) return dp[num][p];
    
                   return dp[num][p] = dive(num - 1, p - 1) + dive(num - p, p);
    
    }
    
     
    
    int main(){
    
                   freopen("div.in","r",stdin);
    
                   freopen("div.out","w",stdout);
    
                   cin >> n >> k;
    
                   int ans = dive(n,k);
    
                   cout << ans << endl;
    
                   return 0;
    
    }

    当然还可以递推求解:

    Code:

    递推:

    #include<bits/stdc++.h>
    
     
    
    using namespace std;
    
     
    
    int n,k;
    
    int ans[210][10];
    
     
    
    int main(){
    
                   freopen("div.in","r",stdin);
    
                   freopen("div.out","w",stdout);
    
                   cin >> n >> k;
    
                   memset(ans,0,sizeof(ans));
    
                   for (int i = 1; i <= n; i++)
    
                                   ans[i][1] = 1;//边界
    
                   for (int i = 1; i <= k; i++)
    
                                   ans[i][i] = 1;//边界
    
                   for (int i = 2; i <= k; i++)
    
                                   for (int j = i; j <= n; j++)
    
                                                  ans[j][i] = ans[j-1][i-1] + ans[j-i][i];
    
                   cout << ans[n][k];
    
                   cout << endl;
    
                   return 0;
    
    }

     

  • 相关阅读:
    分分钟制作微信朋友圈页面
    js模板引擎原理,附自己写的简洁模板引擎
    基于H5 pushState实现无跳转页面刷新
    随手学和记——PHP快速上手基础
    ES5 特性概览
    JavaScript错误和异常
    JavaScript闭包探究
    FastDFS总结
    C++11笔记
    leveldb源码笔记
  • 原文地址:https://www.cnblogs.com/sun915/p/9493484.html
Copyright © 2020-2023  润新知