WHU 1579 Big data (DP)

本文探讨了如何解决背包问题中的序列计数问题,包括序列的定义、解题策略和实现细节。通过实例分析,详细解释了如何利用动态规划解决这类问题,特别关注了特殊情况下的序列区分。

题意:

      f[0]=0,f[i]=f[i-1]+a or b.

      求满足L<=∑f[n]<=R的序列的种数

      n<100.  |a|,|b|<=10000.  |L|,|R|<1e9

 


 

Solution

      其实就是一个背包问题.

      当a=b,序列 0 a a+a和 0 b b+b 竟然算不同的序列= =,巨坑

 

#include <iostream>
#define LL long long
using namespace std;
const int MOD = (int) 1e9 + 7;
const int M = 105;

LL N, a, b, L, R;
LL dp[109][109 * 109];

int main() {
    dp[0][0] = 1;
    for (int i = 1; i <= M; i++)
        for (int j = 0; j <= (i * (i - 1) / 2); j++) {
            dp[i][j] = (dp[i - 1][j] + dp[i][j]) % MOD;
            dp[i][j + i] = (dp[i - 1][j] + dp[i][j + i]) % MOD;
        }

    for (int i = 1; i <= M; i++)
        for (int j =  (i + 1) * i / 2 - 1; j >= 0; j--)
            dp[i][j] = (dp[i][j + 1] + dp[i][j]) % MOD;

    while (cin >> N >> a >> b >> L >> R) {
        if (a > b) swap (a, b);
        LL s = a * (1 + N) * N / 2;
        if (s <= R && b != a ) {
            LL nl = (L - s ) / (b - a), nr = (R - s) / (b - a) + 1;
            if ( (L - s) % (b - a) != 0) nl++;
            if (L - s <= 0) nl = 0;
            if (nl > (N + 1) *N / 2) nl = (N + 1) * N / 2  + 1;
            if (nr > (N + 1) *N / 2) nr = (N + 1) * N / 2 + 1;
            cout << (MOD + dp[N][nl] - dp[N][nr]) % MOD << endl;
        }
        else if (s >= L && s <= R && b == a) {
            LL ans = 1;
            for (int i = 1; i <= N; i++)
                ans = (ans * 2) % MOD;
            cout << ans << endl;
        }
        else
            cout << 0 << endl;
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/keam37/p/4467776.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值