CSA:Count Arrays(dp)

本文探讨了一个有趣的问题:给定长度为N的二进制数组和Q个区间,如何计算满足每个区间内至少包含一个0的数组数量。文章通过动态规划的方法给出了详细的解决方案,并附带了完整的代码实现。

Count Arrays

Time limit: 1000 ms
Memory limit: 256 MB

You are given QQ segments. For every 1 \le i \le Q1iQ, segment number ii is [l_i,r_i][li,ri].

A binary array of length NN is considered good if and only if for each 1 \le i \le Q1iQ there is at least one position between l_ili and r_iri (inclusive) in this array that contains 00.

Find the number of good arrays.

Standard input

The first line contains two integers NN and QQ.

The next QQ lines contain two integers each, l_ili and r_iri, representing the segments.

Standard output

Print the answer modulo 10^9+7109+7 on the first line.

Constraints and notes

  • 1 \le N, Q \le 10^51N,Q105 
  • 1 \le l_i \le r_i \le N1liriN for each 1 \le i \le Q1iQ
InputOutputExplanation
3 2
1 2
2 3
5

Good arrays are 000000001001010010100100101101

5 1
1 5
31

Out of 32 possible arrays only one (1111111111) is bad.

题意:一个N长度的01串和Q个区间,要求每个区间都至少有1个0,问符合的串共有几种?

思路:dp[i]表示前i个位置且s[i]=0的合法方案数(i后面可以看成全为1),我们维护一个最大左界L,方程转移到位置j时dp[j]=sigma(dp[L]~dp[j-1])。

# include <bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
const int maxn = 1e5+30;
int dp[maxn], s[maxn], pre[maxn];
int main()
{
    int n, q, l, r;
    scanf("%d%d",&n,&q);
    while(q--)
    {
        scanf("%d%d",&l,&r);
        pre[r] = max(pre[r], l);
    }
    dp[0] = s[0] = 1;
    int bl=0;
    for(int i=1; i<=n; ++i)
    {
        dp[i] = s[i-1];
        if(bl) dp[i] = (dp[i]-s[bl-1]+mod)%mod;
        bl = max(bl, pre[i]);
        s[i] = (s[i-1]+dp[i])%mod;
    }
    printf("%d\n",bl?(s[n]-s[bl-1]+mod)%mod:s[n]);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值