【详解】Ant Counting POJ - 3046 ⭐⭐⭐ 【多重集组合数】

Ant Counting POJ - 3046

贝西有T种蚂蚁共A只,每种蚂蚁有Ni只,同种蚂蚁不能区分,不同种蚂蚁可以区分,记Sumi为i只蚂蚁构成不同的集合的方案数,问Sumk(S≤k≤B)之和。

Input

第一行4个整数T、A、S、B。 接下来A行,每行一个整数,代表这只蚂蚁的种类。

Output

输出Sumk(S≤k≤B)之和。 (数据范围见原文)

Examples

Sample Input
3 5 2 3
1
2
2
1
3
Sample Output
10

Hint




题意:
题解:

非常经典的多重集组合数问题, 即有N种物品, 第 i 种物品有 ai 个, 从中取出 m 个, 共有多少种取法 ?
d p [ i ] [ j ] : 前 i 种 物 品 取 j 个 的 组 合 数 dp[i][j]:前i种物品取j个的组合数 dp[i][j]:ij
根据加法计数原理, 为了从前 i 种物品中取出 j 个, 需要考虑前 i-1个物品中取出的所有可能. 即
d p [ i ] [ j ] = ∑ k = 0 m i n ( j , a [ i ] ) d p [ i − 1 ] [ j − k ] dp[i][j] = \sum_{k=0}^{min(j,a[i])}dp[i-1][j-k] dp[i][j]=k=0min(j,a[i])dp[i1][jk]

直接计算这个递推关系的话复杂度为O(nm^2), 我们考虑进一步优化
∑ k = 0 m i n ( j , a [ i ] ) d p [ i − 1 ] [ j − k ] = d p [ i − 1 ] [ j ] + d p [ i − 1 ] [ j − 1 ] + . . . + d p [ i − 1 ] [ j − a [ i ] ] + d p [ i − 1 ] [ j − a [ i ] − 1 ] − d p [ i − 1 ] [ j − a [ i ] − 1 ] \sum_{k=0}^{min(j,a[i])}dp[i-1][j-k]=dp[i-1][j]+dp[i-1][j-1]+...+dp[i-1][j-a[i]]+dp[i-1][j-a[i]-1]-dp[i-1][j-a[i]-1] k=0min(j,a[i])dp[i1][jk]=dp[i1][j]+dp[i1][j1]+...+dp[i1][ja[i]]+dp[i1][ja[i]1]dp[i1][ja[i]1] (a[i] <= j, 后两项为手动添加)

∑ k = 0 m i n ( j , a [ i ] ) d p [ i − 1 ] [ j − k ] = d p [ i − 1 ] [ j ] + ∑ k = 0 m i n ( j − 1 , a [ i ] ) − d p [ i − 1 ] [ j − a [ i ] − 1 ] \sum_{k=0}^{min(j,a[i])}dp[i-1][j-k]=dp[i-1][j]+\sum_{k=0}^{min(j-1, a[i])}-dp[i-1][j-a[i]-1] k=0min(j,a[i])dp[i1][jk]=dp[i1][j]+k=0min(j1,a[i])dp[i1][ja[i]1]

∑ k = 0 m i n ( j , a [ i ] ) d p [ i − 1 ] [ j − k ] = d p [ i − 1 ] [ j ] + d p [ i ] [ j − 1 − a [ i ] ] − d p [ i − 1 ] [ j − a [ i ] − 1 ] \sum_{k=0}^{min(j,a[i])}dp[i-1][j-k]=dp[i-1][j]+dp[i][j-1-a[i]]-dp[i-1][j-a[i]-1] k=0min(j,a[i])dp[i1][jk]=dp[i1][j]+dp[i][j1a[i]]dp[i1][ja[i]1]

当j < a[i]时更简单了, 可以消去后面项推出dp[i][j] = d[i-1][j] + d[i-1][j - a[i] - 1]

注意题目要求取后6位, 要%1e6, 同时要考虑负数, 需要(…+mod)%mod

经验小结:

看到这种与组合数学相关的问题, 大胆先去推公式, 找出前项和后项间的关系, 从而简化递推式


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef  long long LL;
const int inf = 1<<30;
const LL maxn = 1e5+10;
const int mod = 1e6;

int N, M, l, r, a[1010];
int dp[1010][maxn]; //前i种取j个的组合数
int main()
{
    int input;
    cin >> N >> M >> l >> r;
    for(int i = 1; i <= M; ++i){
        cin >> input;
        ++a[input];
    }

    //初始化, 一个也不取总有一种
    for(int i = 0; i <= N; ++i)
        dp[i][0] = 1;

    for(int i = 1; i <= N; ++i){
        for(int j = 1; j <= M; ++j){
            if(j-a[i]-1 >= 0) //j>=a[i]时
                dp[i][j] = (dp[i][j-1]+dp[i-1][j]-dp[i-1][j-1-a[i]]+mod)%mod;
            else              //j<a[i]时
                dp[i][j] = (dp[i][j-1]+dp[i-1][j]+mod)%mod;
        }
    }
    int ans = 0;
    for(int i = l; i <= r; ++i)
        ans = (ans+dp[N][i]+mod)%mod;
    cout << ans << endl;

	return 0;
}
boosting-crowd-counting-via-multifaceted-attention是一通过多方面注意力提升人群计数的方法。该方法利用了多个方面的特征来准确估计人群数量。 在传统的人群计数方法中,往往只关注人群的整体特征,而忽略了不同区域的细节。然而,不同区域之间的人群密度可能存在差异,因此细致地分析这些区域是非常重要的。 该方法首先利用卷积神经网络(CNN)提取图像的特征。然后,通过引入多个注意力机制,分别关注图像的局部细节、稀疏区域和密集区域。 首先,该方法引入了局部注意力机制,通过对图像的局部区域进行加权来捕捉人群的局部特征。这使得网络能够更好地适应不同区域的密度变化。 其次,该方法采用了稀疏区域注意力机制,它能够识别图像中的稀疏区域并将更多的注意力放在这些区域上。这是因为稀疏区域往往是需要重点关注的区域,因为它们可能包含有人群密度的极端变化。 最后,该方法还引入了密集区域注意力机制,通过提取图像中人群密集的区域,并将更多的注意力放在这些区域上来准确估计人群数量。 综上所述,boosting-crowd-counting-via-multifaceted-attention是一通过引入多个注意力机制来提高人群计数的方法。它能够从不同方面细致地分析图像,并利用局部、稀疏和密集区域的特征来准确估计人群数量。这个方法通过考虑人群分布的细节,提供了更精确的人群计数结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值