Ant Counting POJ - 3046【dp-多重集组合数-模板】

题意简述:有t种蚂蚁 ,a个蚂蚁 每个蚂蚁属于一个种类 不同类蚂蚁可以区分 同类蚂蚁不可以区分 求这些蚂蚁组成大小为s s+1…b集合的组合数


多重集组合数模板

n种物品,第i种物品有ai个,不同种类物品可以互相区分但是相同种类无法区分。从这些物品中取出m个,求方案数。
推导

——方法来源于《挑战程序设计竞赛》P68-69
注意这里的物品种类编号是从0~n-1的


Code View

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
#define MAXN 1005
#define INF 0x3f3f3f3f
#define MOD 1000000
int dp[MAXN][MAXN*10];//dp[i+1][j] 前i种物品中取j个
/*
dp[i+1][j]=sigma dp[i][j-k]|0<=k<=min(j,a[i])

dp[i+1][j-1]=sigma dp[i][j-1-k] |0<=k<=min(j-1,a[i])
sigma dp[i][j-k] =dp[i][j]+dp[i][j-1]+dp[i][j-2]+···+dp[i][j-a[i]]
sigma dp[i][j-1-k]=dp[i][j-1]+dp[i][j-2]+···+dp[i][j-1-a[i]]sigma dp[i][j-k]=sigma dp[i][j-1-k]+dp[i][j]-dp[i][j-1-a[i]]
进行代换 dp[i+1][j]=dp[i+1][j-1]+dp[i][j]-dp[i][j-1-a[i]]

*/
int n,tot,s,b;
int a[MAXN];
int main()  
{
    scanf("%d %d %d %d",&n,&tot,&s,&b);
    for(int i=1;i<=tot;i++)
    {
        int tmp;
        scanf("%d",&tmp);
        a[tmp-1]++;
    }
    for(int i=0;i<=n;i++)
        dp[i][0]=1;
    for(int i=0;i<n;i++)
        for(int j=1;j<=b;j++)
            if(j-1-min(j,a[i])>=0)
                dp[i+1][j]=(dp[i+1][j-1]+dp[i][j]-dp[i][j-1-min(j,a[i])]+MOD)%MOD;
            else dp[i+1][j]=(dp[i+1][j-1]+dp[i][j])%MOD;             
    int ans=0; 
    for(int i=s;i<=b;i++)
        ans=(dp[n][i]+ans)%MOD;
    printf("%d\n",ans);
    return 0;
}

后话
书上的定义和我平时用惯的不太一样,因为书上的a数组是从0~n-1
我还是觉得 dp[i+1][j]的定义方式有点strange
我个人比较习惯dp[i][j]:前i种物品中取j个
然后自己试了一下

AC code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
#define MAXN 1005
#define INF 0x3f3f3f3f
#define MOD 1000000
int dp[MAXN][MAXN*10];
int n,tot,s,b;
int a[MAXN];
int main()  
{
    scanf("%d %d %d %d",&n,&tot,&s,&b);
    for(int i=1;i<=tot;i++)
    {
        int tmp;
        scanf("%d",&tmp);
        a[tmp]++;
    }
    for(int i=0;i<=n;i++)
        dp[i][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=b;j++)
            if(j-1-min(j,a[i])>=0)
                dp[i][j]=(dp[i][j-1]+dp[i-1][j]-dp[i-1][j-1-min(j,a[i])]+MOD)%MOD;
            else dp[i][j]=(dp[i][j-1]+dp[i-1][j])%MOD;             
    int ans=0; 
    for(int i=s;i<=b;i++)
        ans=(dp[n][i]+ans)%MOD;
    printf("%d\n",ans);
    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、付费专栏及课程。

余额充值