zoukankan      html  css  js  c++  java
  • bzoj1630 / bzoj2023 [Usaco2005 Nov]Ant Counting 数蚂蚁

    Description

        有一天,贝茜无聊地坐在蚂蚁洞前看蚂蚁们进进出出地搬运食物.很快贝茜发现有些蚂蚁长得几乎一模一样,于是她认为那些蚂蚁是兄弟,也就是说它们是同一个家族里的成员.她也发现整个蚂蚁群里有时只有一只出来觅食,有时是几只,有时干脆整个蚁群一起出来.这样一来,蚂蚁们出行觅食时的组队方案就有很多种.作为一头有数学头脑的奶牛,贝茜注意到整个蚂蚁群由T(1≤T≤1000)个家族组成,她将这些家族按1到T依次编号.编号为i的家族里有Ni(1≤Ni≤100)只蚂蚁.同一个家族里的蚂蚁可以认为是完全相同的.
        如果一共有S,S+1….,B(1≤S≤B≤A)只蚂蚁一起出去觅食,它们一共能组成多少种不同的队伍呢?注意:只要两支队伍中所包含某个家族的蚂蚁数不同,我们就认为这两支队伍不同.由于贝茜无法分辨出同一家族的蚂蚁,所以当两支队伍中所包含的所有家族的蚂蚁数都相同时,即使有某个家族换了几只蚂蚁出来,贝茜也会因为看不出不同而把它们认为是同一支队伍.    比如说,有个由3个家族组成的蚂蚁群里一共有5只蚂蚁,它们所属的家族分别为1,1,2,2,3.于是出去觅食时它们有以下几种组队方案:
      ·1只蚂蚁出去有三种组合:(1)(2)(3)
      ·2只蚂蚁出去有五种组合:(1,1)(1,2)(1,3)(2,2)(2,3)
      ·3只蚂蚁出去有五种组合:(1,1,2)(1,1,3)(1,2,2)(1,2,3)(2,2,3)
      ·4只蚂蚁出去有三种组合:(1,2,2,3)(1,1,2,2)(1,1,2,3)
      ·5只蚂蚁出去有一种组合:(1,1,2,2,3)
        你的任务就是根据给出的数据,计算蚂蚁们组队方案的总数.

    Input

        第1行:4个用空格隔开的整数T,A,S,B.
        第2到A+1行:每行是一个正整数,为某只蚂蚁所在的家族的编号.

    Output

     
        输出一个整数,表示当S到B(包括S和B)只蚂蚁出去觅食时,不同的组队方案数.
        注意:组合是无序的,也就是说组合1,2和组合2,1是同一种组队方式.最后的答案可能很大,你只需要输出答案的最后6位数字.注意不要输出前导0以及多余的空格.
     

    Sample Input

    3 5 2 3
    1
    2
    2
    1
    3

    INPUT DETAILS:

    Three types of ants (1..3); 5 ants altogether. How many sets of size 2 or
    size 3 can be made?

    Sample Output

    10

    OUTPUT DETAILS:

    5 sets of ants with two members; 5 more sets of ants with three members
     

     
    错觉:组合数学???(大雾)
    然鹅是(万能)dp
    设$f[i][j]$表示从前$i$个家族选出$j$只蚂蚁的方案数
    则 $f[i][j]+=sum_{u=1}^{min(j,d[i])}f[i-1][j-u]$
    但是会MLE+TLE
    于是我们可以滚动数组+前缀和。
    转化后就变成了$f[j]=sum[j]-sum[j-d[i]-1]$
    end.
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cctype>
     5 #define re register
     6 using namespace std;
     7 void read(int &x){
     8     char c=getchar();x=0;
     9     while(!isdigit(c)) c=getchar();
    10     while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
    11 }
    12 int min(int a,int b){return a<b?a:b;}
    13 #define p 1000000
    14 int t,a,s,b,q,f[100002],d[1002],sum[100002],ans;
    15 int main(){
    16     read(t);read(a);read(s);read(b); f[0]=sum[0]=1;
    17     for(re int i=1;i<=a;++i) read(q),++d[q];
    18     for(re int i=1;i<=t;++i){
    19         for(re int j=1;j<=b;++j) sum[j]=(sum[j-1]+f[j])%p;//前缀和处理
    20         for(re int j=b;j>=1;--j){
    21             if(j<=d[i]) f[j]=sum[j]%p;//注意边界
    22             else f[j]=(sum[j]-sum[j-d[i]-1])%p;
    23         }
    24     }
    25     for(re int i=s;i<=b;++i) ans=(ans+f[i])%p;
    26     printf("%d",ans);
    27     return 0;
    28 }
    View Code
  • 相关阅读:
    jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解
    jQuery 源码解析(二十三) DOM操作模块 替换元素 详解
    jQuery 源码解析(二十二) DOM操作模块 复制元素 详解
    jQuery 源码分析(二十一) DOM操作模块 删除元素 详解
    jQuery 源码分析(二十) DOM操作模块 插入元素 详解
    jQuery 源码分析(十九) DOM遍历模块详解
    python 简单工厂模式
    python 爬虫-协程 采集博客园
    vue 自定义image组件
    微信小程序 image组件坑
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9864860.html
Copyright © 2011-2022 走看看