POJ 3046

Posted wpbing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3046相关的知识,希望对你有一定的参考价值。

题目大意:蚂蚁牙黑,蚂蚁牙红:有A只蚂蚁,来自T个家族,分别记为ant[i]个。同一个家族的蚂蚁长得一样,但是不同家族的蚂蚁牙齿颜色不同。任取n只蚂蚁(S <= n <= B),求能组成几种集合?

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

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

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

技术分享图片
#include<stdio.h>
#include<string.h>
int dp[1005][10050];
int num[10050];
int main(){
    int n,m,a,b,x;
    while(scanf("%d%d%d%d",&n,&m,&a,&b)!=EOF){
        memset(num,0,sizeof(num));
        for(int i=0;i<m;i++){
            scanf("%d",&x);
            num[x]++;
        }
        memset(dp,0,sizeof(dp));
        for(int i=0;i<=num[1];i++) dp[1][i]=1;
        for(int i=2;i<=n;i++){
            for(int j=0;j<=b;j++){
                for(int k=0;k<=num[i];k++){
                    if(j>=k) {
                    dp[i][j]+=dp[i-1][j-k];
                    dp[i][j]%=1000000;
                    }
                }
            }
        }
        int ans=0;
        for(int i=a;i<=b;i++){
            ans+=dp[n][i];
            ans%=1000000;
        }
        printf("%d
",ans);
    }
    return 0;
}
技术分享图片

还有一种

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

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

以上是关于POJ 3046的主要内容,如果未能解决你的问题,请参考以下文章

poj 3046 Ant Counting

poj 3046 Ant Counting

POJ 3046

Ant Counting POJ 3046(计数dp)

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

OI每周刷题记录