zoukankan      html  css  js  c++  java
  • P1655 小朋友的球

    P1655 小朋友的球

    题目描述

    @发源于 小朋友最近特别喜欢球。有一天他脑子抽了,从口袋里拿出了N个不同的球,想把它们放到M个相同的盒子里,并且要求每个盒子中至少要有一个球,他好奇有几种放法,于是尝试编程实现,但由于他天天不好好学习,只会上B站看游泳教练,于是他向你求助。

    输入输出格式

    输入格式:

    多组数据,每行两个数N,M。

    输出格式:

    每组数据一行,表示方案数。

    输入输出样例

    输入样例#1: 复制
    4 2
    1 1
    输出样例#1: 复制
    7
    1

    说明

    【样例解释】

    N=4,M=2

    1,2 3 4

    2,1 3 4

    3,1 2 4

    4,1 2 3

    1 2,3 4

    1 3,2 4

    1 4,2 3

    对于20%的数据,满足1≤N,M≤10;

    对于100%的数据,满足1≤N,M≤100,数据组数≤10。

    洛谷题解:

    • 简单的动态规划,但是要加上高精度运算,不然只能得 20 分。本题和 放苹果 有些类似,但是盒子不能空着不放,也就是楼下所说的 Stirling数,应用于组合数学领域

    • 状态转移方程:f[i][j]=f[i1][j1]+f[i1][j]×j

    加一个盒子加一个球

    加一个球

    为什么不能加一个盒子,肯定不能加一个盒子,因为之前的是固定的

    状态怎么转移

    stirling数,递推公式s[i][j]=s[i-1][j]*j+s[i-1][j-1]这个在各类组合数学书籍上均有证明,现截取一段

    S(p,k)的一个组合学解释是:将p个物体划分成k个非空的不可辨别的(可以理解为盒子没有编号)集合的方法数。

    k!S(p,k)是把p个人分进k间有差别(如:被标有房号)的房间(无空房)的方法数。

    S(p,k)的递推公式是:S(p,k)=k*S(p-1,k)+S(p-1,k-1) ,1<= k<=p-1

    边界条件:S(p,p)=1 ,p>=0 S(p,0)=0 ,p>=1

    递推关系的说明:

    考虑第p个物品,p可以单独构成一个非空集合,此时前p-1个物品构成k-1个非空的不可辨别的集合,方法数为S(p-1,k-1);

    也可以前p-1种物品构成k个非空的不可辨别的集合,第p个物品放入任意一个中,这样有k*S(p-1,k)种方法。

    注意:当m>n||m==0时直接输出0,!!!因为这个wa了好多次 也就只要加上高精就行了,先贴上c++代码:

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<iostream>
     6 #include<algorithm>
     7 #define inf 999999999
     8 #define For(i,a,b) for(i=a;i<=b;++i)
     9 #define rep(i,a,b) for(i=a;i>=b;--i)
    10 #define mm(a,b) memset(a,b,sizeof(a))
    11 #define ll long long
    12 using namespace std;
    13 ll read(){
    14     ll sum=0,flag=1;
    15     char c=getchar();
    16     while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();}
    17     while(c>='0'&&c<='9')sum=sum*10+c-'0',c=getchar();
    18     return sum*flag;
    19 }
    20 ll maxx(ll x,ll y){
    21     if(x<y)return y;
    22     return x;
    23 }
    24 ll minn(ll x,ll y){
    25     if(x<y)return x;
    26     return y;
    27 }
    28 ll abss(ll x){
    29     if(x>=0)return x;
    30     return -x;
    31 }
    32 struct node{
    33     ll a[500],len;
    34     node(){mm(a,0);len=0;}//记得初始化
    35 };
    36 node t[111][111];
    37 node operator + (node c,node d){
    38     node h;h.len=maxx(c.len,d.len);
    39     int i;
    40     for(i=1;i<=h.len;i++){
    41         h.a[i]+=c.a[i]+d.a[i];
    42         if(h.a[i]>=10){
    43             h.a[i+1]+=h.a[i]/10;
    44             h.a[i]%=10;
    45             if(i==h.len)h.len++;
    46         }
    47     }
    48     return h;
    49 }
    50 node operator * (node c,ll u){
    51     node h;h.len=c.len;
    52     int i;
    53     for(i=1;i<=h.len;i++){
    54         h.a[i]+=c.a[i]*u;
    55         if(h.a[i]>=10){
    56             h.a[i+1]+=h.a[i]/10;
    57             h.a[i]%=10;
    58             if(i==h.len)h.len++;
    59         }
    60     }
    61     return h;
    62 }
    63 int main(){
    64     ll i,j,m,n;
    65     For(i,1,100)t[i][0].a[1]=0,t[i][i].a[1]=t[i][1].a[1]=1,t[i][0].len=t[i][i].len=t[i][1].len=1;
    66     For(i,2,100){
    67         For(j,2,i-1){
    68             t[i][j]=t[i-1][j-1]+t[i-1][j]*j;
    69         }
    70     }
    71     while(scanf("%lld%lld",&m,&n)!=EOF){
    72         if(n==0||n>m){printf("0
    ");continue;}
    73         rep(i,t[m][n].len,1)printf("%lld",t[m][n].a[i]);
    74         printf("
    ");
    75     }    
    76     return 0;
    77 }
  • 相关阅读:
    2015.07.20MapReducer源码解析(笔记)
    Hive(笔记)
    HDFS入门(1)
    Zookepper(2015.08.16笔记)
    USB_ModeSwitch 介绍(转)
    Perl 模块 Getopt::Std 和 Getopt::Long
    在linux下设置开机自动启动程序的方法
    gcc Makefile 入门
    Linuxexec函数族及system函数
    signal(SIGHUP, SIG_IGN)的含义
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7741754.html
Copyright © 2011-2022 走看看