Ant Counting

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 3   Accepted Submission(s) : 2
Problem Description
Bessie was poking around the ant hill one day watching the ants march to and fro while gathering food. She realized that many of the ants were siblings, indistinguishable from one another. She also realized the sometimes only one ant would go for food, sometimes a few, and sometimes all of them. This made for a large number of different sets of ants!

Being a
bit mathematical, Bessie started wondering. Bessie noted that the hive has T (1
<= T <= 1,000) families of ants which she labeled 1..T (A ants
altogether). Each family had some number Ni (1 <= Ni <= 100) of ants.

How many groups of sizes S, S+1, ..., B (1 <= S <= B <= A) can
be formed?

While observing one group, the set of three ant families was
seen as {1, 1, 2, 2, 3}, though rarely in that order. The possible sets of
marching ants were:

3 sets with 1 ant: {1} {2} {3}
5 sets with 2
ants: {1,1} {1,2} {1,3} {2,2} {2,3}
5 sets with 3 ants: {1,1,2} {1,1,3}
{1,2,2} {1,2,3} {2,2,3}
3 sets with 4 ants: {1,2,2,3} {1,1,2,2} {1,1,2,3}

1 set with 5 ants: {1,1,2,2,3}

Your job is to count the number of
possible sets of ants given the data above.

 
Input
* Line 1: 4 space-separated integers: T, A, S, and B
<br> <br>* Lines 2..A+1: Each line contains a single integer that is
an ant type present in the hive
 
Output
* Line 1: The number of sets of size S..B (inclusive)
that can be created. A set like {1,2} is the same as the set {2,1} and should
not be double-counted. Print only the LAST SIX DIGITS of this number, with no
leading zeroes or spaces.
 
Sample Input
3 5 2 3
1
2
2
1
3
 
Sample Output
10
 

分析:

多重集组合数也是由多重背包问题拓展出来的一类经典问题。这里仍然给大家讲2种方法:

①朴素方法:

状态:dp[i][j]:前i种中选j个可以组成的种数

决策:第i种选k个,k<=ant[i] && j-k>=0

转移:dp[i][j]=Σdp[i-1][j-k]

复杂度为O(B*Σant[i])即O(B*A)也即O(A^2),虽说这题A最大可到1e5,但是实际数据水,能过

②优化递推式

状态:dp[i][j]:前i种中选j个可以组成的种数

决策:第i种不选或者至少选一个

转移:

1.若不选,显然为dp[i-1][j]

2.若至少选一种,那么为dp[i][j-1]-dp[i-1][j-ant[i]-1]

我们这样来理解,dp[i][j-1] 理解为已经选了第i种一个,至于还选不选这里我们不管它,所以它可以用来代表至少选一个

但是dp[i][j-1]还有一层含义便是前i种中选j-1个可以组成的种数,所以它包含了选ant[i]个第i种,即dp[i-1][j-ant[i]-1],但

dp[i][j] 最多选ant[i]个第i种,所以最后要减去这一种。

所以 dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-ant[i]-1]

复杂度为O(T*B)

 #include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
const int mod = ;
int dp[][];
int main()
{
int ant[];
int t, a, s, b;
cin >> t >> a >> s >> b;
memset(ant, , sizeof(ant));
int i;
int j;
for (i = ; i <= a; i++)
{
cin >> j;
ant[j]++;
}
for (i = ; i <= t; i++) dp[i][] = ;
dp[][] = dp[][] = ;
for (i = ; i <= t; i++)
{
for (j = ; j <= b; j++)
{
if (j - ant[i] - >= )
{//在取模时若出现了减法运算则需要先+Mod再对Mod取模,防止出现负数(如5%4-3%4为负数)
dp[i][j] = (dp[i - ][j] + dp[i ][j - ] - dp[i - ][j - ant[i] - ] + mod) % mod;
}
else
{
dp[i][j] = (dp[i - ][j] + dp[i][j - ])%mod;
}
}
}
int sum = ;
for (i = s; i <= b; i++)
sum = (sum + dp[t][i]) % mod;
cout << sum << endl;
return ;
}

为了节约空间%2;

#include<iostream>
using namespace std;
#define MOD 1000000
int T, A, S, B;
int ant[];
int dp[][];
int ans;
int main()
{
scanf("%d%d%d%d", &T, &A, &S, &B);
for (int i = ; i <= A; i++)
{
int aa;
scanf("%d", &aa);
ant[aa]++;
}
dp[][] = dp[][] = ;
for (int i = ; i <= T; i++)
for (int j = ; j <= B; j++)
if (j - ant[i] - >= ) dp[i % ][j] = (dp[(i - ) % ][j] + dp[i % ][j - ] - dp[(i - ) % ][j - ant[i] - ] + MOD) % MOD; //在取模时若出现了减法运算则需要先+Mod再对Mod取模,防止出现负数(如5%4-3%4为负数)
else dp[i % ][j] = (dp[(i - ) % ][j] + dp[i % ][j - ]) % MOD;
for (int i = S; i <= B; i++)
ans = (ans + dp[T % ][i]) % MOD;
printf("%d\n", ans);
return ;
}
 

poj 3046 Ant Counting(多重集组合数)的更多相关文章

  1. POJ 3046 Ant Counting ( 多重集组合数 && 经典DP )

    题意 : 有 n 种蚂蚁,第 i 种蚂蚁有ai个,一共有 A 个蚂蚁.不同类别的蚂蚁可以相互区分,但同种类别的蚂蚁不能相互区别.从这些蚂蚁中分别取出S,S+1...B个,一共有多少种取法. 分析 :  ...

  2. poj3046 Ant Counting——多重集组合数

    题目:http://poj.org/problem?id=3046 就是多重集组合数(分组背包优化): 从式子角度考虑:(干脆看这篇博客) https://blog.csdn.net/viphong/ ...

  3. poj 3046 Ant Counting

    Ant Counting Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4982   Accepted: 1896 Desc ...

  4. poj 3046 Ant Counting (DP多重背包变形)

    题目:http://poj.org/problem?id=3046 思路: dp [i] [j] :=前i种 构成个数为j的方法数. #include <cstdio> #include ...

  5. poj 3046 Ant Counting——多重集合的背包

    题目:http://poj.org/problem?id=3046 多重集合的背包问题. 1.式子:考虑dp[ i ][ j ]能从dp[ i-1 ][ k ](max(0 , j - c[ i ] ...

  6. POJ 3046 Ant Counting DP

    大致题意:给你a个数字,这些数字范围是1到t,每种数字最多100个,求问你这些a个数字进行组合(不包含重复),长度为s到b的集合一共有多少个. 思路:d[i][j]——前i种数字组成长度为j的集合有多 ...

  7. POJ 3046 Ant Counting(递推,和号优化)

    计数类的问题,要求不重复,把每种物品单独考虑. 将和号递推可以把转移优化O(1). f[i = 第i种物品][j = 总数量为j] = 方案数 f[i][j] = sigma{f[i-1][j-k], ...

  8. 【POJ - 3046】Ant Counting(多重集组合数)

    Ant Counting 直接翻译了 Descriptions 贝西有T种蚂蚁共A只,每种蚂蚁有Ni只,同种蚂蚁不能区分,不同种蚂蚁可以区分,记Sum_i为i只蚂蚁构成不同的集合的方案数,问Sum_k ...

  9. POJ_3046_Ant_Counting_(动态规划,多重集组合数)

    描述 http://poj.org/problem?id=3046 n种蚂蚁,第i种有ai个,不同种类的蚂蚁可以相互区分,但同一种类的蚂蚁不能相互区分,从这些蚂蚁中取出s,s+1,s+2,...,b- ...

随机推荐

  1. C++零散知识点

    CString strDayofWeek = _T(""); 的意思 1.sComment是自定义的CString类型变量,代表什么意思自己说了算2._T是一个宏,作用是让你的程序 ...

  2. 玩转X-CTR100 l STM32F4 l SD卡FatFs文件系统

    我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] X-CTR100控制器具有SD卡接口,本教程使用免费 ...

  3. Loom

    <iframe width="630" height="394" src="https://www.useloom.com/embed/a9d4 ...

  4. oracle 统计sql

    最近在研究项目时发现如下sql, select 3 agentOfGCount, 0 workingCount, 0 restingCount, 0 busyingCount, 0 connectin ...

  5. java poi 写入大量数据到excel中

    最近在利用poi往excel中写入大量数据时,发现excel2003最多只支持65535条,大量数据时容易造成oom,上网查了一下api,发现目前对于2003,每个sheet最多支持65535条,若数 ...

  6. HAWQ + MADlib 玩转数据挖掘之(七)——关联规则方法之Apriori算法

    一.关联规则简介 关联规则挖掘的目标是发现数据项集之间的关联关系,是数据挖据中一个重要的课题.关联规则最初是针对购物篮分析(Market Basket Analysis)问题提出的.假设超市经理想更多 ...

  7. QNX的深度嵌入过程

    QNX的深度嵌入过程   1.1           QNX目标系统嵌入 利用QNX的模块性和和可裁剪性,其嵌入过程一般是: 构建Buildfile -> 编译buildfile生成系统映象文件 ...

  8. [LeetCode&Python] Problem 669. Trim a Binary Search Tree

    Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so that a ...

  9. 洛谷 1020:导弹拦截(DP,LIS)

    题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...

  10. [Boolan-C++学习笔记]第二周整理

    1.对于String类型的类(含有指针) 其中的指针成员能够灵活的申请存储空间,但指针操作又带来内存泄漏的风险,变更指针的操作需要尤为谨慎. 要点在于写好BigThree 构造函数 { 完成成员初始化 ...