POJ3046 动态规划 多重集组合数

这篇博客探讨了POJ3046问题,涉及动态规划和多重集组合数的计算。作者强调了解决问题时前缀和优化和滚动数组优化的重要性,并提醒注意初始化及循环上下界细节的处理。文章包含解题思路和代码实现。
摘要由CSDN通过智能技术生成

题意:

蚂蚁牙黑,蚂蚁牙红:有A只蚂蚁,来自T个家族。同一个家族的蚂蚁长得一样,但是不同家族的蚂蚁牙齿颜色不同。任取n只蚂蚁(S<=n<=B),求能组成几种集合?

思路:
1、《挑战》P69 前缀和优化;
2、滚动数组优化。
反思:
初始化以及循环上下界的细节要考虑清楚。
代码:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

const int MOD = 1e6;

int c[1000 + 10];
int dp[2][100000 + 10];

int main()
{
    int t, a, s, b;
    scanf("%d%d%d%d", &t, &a, &s, &b);
    for(int i = 0; i < a; i++)
    {
        int x; scanf("%d", &x);
        c[x]++;
    }
    dp[0][0] = dp[1][0] = 1;
    for(int i = 1; i <= t; i++)
    {
        for(int j = 1; j <= b; j++)
        {
            if(j <= c[i])
            {
                dp[i & 1][j] = (dp[i & 1][j - 1] + dp[(i - 1) & 1][j]) % MOD;
            }
            else
            {
                dp[i & 1][j] = (dp[(i - 1) & 1][j] + dp[i & 1][j - 1] - dp[(i - 1) & 1][j - 1 - c[i]] + MOD) % MOD;
            }
        }
    }
    int ans = 0;
    for(int j = s; j <= b; j++)
    {
        ans = (ans + dp[t & 1][j]) % MOD;
    }
    printf("%d\n", ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值