• POJ1430


    这个题目初看上去是一个排列组合题,而实际上……也是一个排列组合题。

    题目描述是:

    Description

    The Stirling number of the second kind S(n, m) stands for the number of ways to partition a set of n things into m nonempty subsets. For example, there are seven ways to split a four-element set into two parts: 

    {1, 2, 3} U {4}, {1, 2, 4} U {3}, {1, 3, 4} U {2}, {2, 3, 4} U {1}
    
    {1, 2} U {3, 4}, {1, 3} U {2, 4}, {1, 4} U {2, 3}.


    There is a recurrence which allows to compute S(n, m) for all m and n. 

    S(0, 0) = 1; S(n, 0) = 0 for n > 0; S(0, m) = 0 for m > 0;
    S(n, m) = m S(n - 1, m) + S(n - 1, m - 1), for n, m > 0.


    Your task is much "easier". Given integers n and m satisfying 1 <= m <= n, compute the parity of S(n, m), i.e. S(n, m) mod 2. 


    Example 

    S(4, 2) mod 2 = 1.


    Task 

    Write a program which for each data set: 
    reads two positive integers n and m, 
    computes S(n, m) mod 2, 
    writes the result. 

    Input

    The first line of the input contains exactly one positive integer d equal to the number of data sets, 1 <= d <= 200. The data sets follow. 

    Line i + 1 contains the i-th data set - exactly two integers ni and mi separated by a single space, 1 <= mi <= ni <= 10^9. 

    Output

    The output should consist of exactly d lines, one line for each data set. Line i, 1 <= i <= d, should contain 0 or 1, the value of S(ni, mi) mod 2.

    Sample Input

    1
    4 2

    Sample Output

    1
     根据题目给出的递推公式,
    S(n, m) = m S(n - 1, m) + S(n - 1, m - 1), for n, m > 0
    显然
      对于m为偶数,S(n,m)=S(n-1,m-1);
      m为奇数,S(n,m)=S(n-1,m)+S(n-1,m-1)=S(n-1,m)+S(n-2,m-2)(m为奇数,则m-2为偶数)
    这样的话就没有m这个系数,得到一个递推。
    但是问题又来了,这个题目n和m都太大,如果是直接地递推,肯定是承受不住的。
    那么就要想想别的办法,在网上看到有人讲到的方法就是根据画图,什么意思呢?
    以n为x轴,m为y轴
    数形结合,当m为偶数的时候可以变为m-1,当m为奇数的时候可以变为m和m-2,这样就是全部是奇数了。
    同时又一个关键的地方需要理解。求S(n,m)就是求又多上条路径从(0,0)到(n,m)仔细理解一下。
    这样的话思路又变化到排列组合上来。上面说到所有的偶数m都会变成m-1(奇数),同时对于奇数(n,m)可以变为(n-1,m)和(n-2,m-2)(其实就是两条路)
    这样的话就是总共有多少种走法呢。
    总共要横着走n-m步,斜着走(即从n,m变为n-2,m-2)(m-1)/2步。
    总用要走n-m+(m-1)/2步,
    这样总路径数就是C(n-m+(m-1)/2,(m-1)/2)。
    于是听过欧拉函数的类似性质就可以迅速地得到所求的答案了呢。
    我的代码:

    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    int d,n,m;
    
    int count(int x)
    {
        return x==0?0:x/2+count(x/2);
    }
    
    int main()
    {
        scanf("%d",&d);
        while (d--)
        {
            scanf("%d%d",&n,&m);
            n-=m,m=(m-1)/2;
            if (count(n+m)==count(n)+count(m)) puts("1");
                else puts("0");
        }
        return 0;
    }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    JavaScript学习总结(5)——Javascript面向(基于)对象编程
    JavaScript学习总结(4)——JavaScript数组
    高性能Web动画和渲染原理系列(4)“Compositor-Pipeline演讲PPT”学习摘要【华为云技术分享】
    AI:为你写诗,为你做不可能的事
    鲲鹏性能优化十板斧(二)——CPU与内存子系统性能调优
    鲲鹏性能优化十板斧——鲲鹏处理器NUMA简介与性能调优五步法
    华为鲲鹏云之我见
    一站式应用平台,华为云实现自动化构建知识图谱
    化鲲为鹏,我有话说 ,鲲鹏ARM架构的优势
    【读一本书】《昇腾AI处理器架构与编程》--神经网络基本知识学习(1)
  • 原文地址:https://www.cnblogs.com/lochan/p/3306956.html
Copyright © 2020-2023  润新知