CDOJ 1307 ABCDE 前缀和优化dp

ABCDE

题目连接:

http://acm.uestc.edu.cn/#/problem/show/1307

Description

Binary-coded decimal (BCD) is a kind of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits.

Awesome Binary-Coded Decimal (ABCD) is, under the above conditions, any number represented by corresponding binary value won't exceed \(9\).

For example, in \(\\{8,4,2,1\\}\) encoding, \(1111\) is \(15\), exceed \(9\), so \(\\{8,4,2,1\\}\) encoding is BCD but not ABCD. In \(\\{2,4,2,1\\}\) encoding, any number represented by corresponding binary value won't exceed \(9\), so \(\\{2,4,2,1\\}\) encoding is ABCD.

Now, let's talk about ABCDE (Awesome Binary-Coded Decimal Extension).

An n-ABCDE is such a encoding that can only represent \(0\) to \(n\), and every number from \(0\) to \(n\) can be represented by one or more binary values. So \(\\{2,4,2,1\\}\) is a \(9\)-ABCDE and \(\\{8,4,2,1\\}\) is a \(15\)-ABCDE as we mentioned above. In addition, \(\\{16,8,4,2,1\\}\) is a \(31\)-ABCDE.

Two encoding will be considered different if they have different length, or they have different number set, with the number of occurrence of each number considered. More precisely, two different coding will have such a number that occur different times.

So, \(\\{2,4,2,1\\}\) encoding is the same with the \(\\{1,2,2,4\\}\) encoding, but it is different from \(\\{2,4,4,1\\}\).

Now, given a number \(n\), can you tell me how many different \(n\)-ABCDEs?

Input

There is an integer \(T\) in the first line, indicates the number of test cases.

For each test, the only line contains a integer \(n\).

\(1\leq T\leq 5000\)

\(1\leq n \leq 5000\)

Output

For each test, output an integer in one line, which is the number of different \(n\)-ABCDEs. As the answer may be too large, output it modulo \((10^9+7)\) (i.e. if the answer is \(X\), you should output \(X\ \%\ (10^9+7)\)).

Sample Input

5
1
2
3
4
5

Sample Output

1
1
2
2
4

Hint

题意

在数电中,有一种码,类似BCD码这种玩意儿

第i位如果为1的话,那么ans+=a[i],a[i]是这一位的位权

然后现在给你一个n,问你一共有多少种码可以表示1~n的所有数呢?

1,1,2和2,1,1视作一样。

题解:

首先考虑这个东西,如果不视作一样的话,就很简单了

dp[i]表示当前和为i的方案数,显然这个玩意儿能够一直转移到2i-1去。

由于视作一样,那么我们只要维护一个当前的最大值就好了,保证这个序列是递增的,这样就都不会一样了。

dp[i][j]表示现在和为i,最大值为j的方案数有多少。

这个转移发现可以用前缀和优化,这样就是n^2的了。

代码

#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
const int maxn = 5005;
int dp[maxn][maxn];
int sum[maxn][maxn];
void init()
{
    dp[0][0]=1;
    for(int i=0;i<=5000;i++)sum[0][i]=1;
    for(int i=1;i<=5000;i++)
    {
        for(int j=1;j<=5000;j++)
            if(j*2-1<=i)dp[i][j]=(dp[i][j]+sum[i-j][j])%mod;
        sum[i][0]=dp[i][0];
        for(int j=1;j<=5000;j++)
            sum[i][j]=(sum[i][j-1]+dp[i][j])%mod;
    }
}
int main()
{
    init();
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        printf("%d\n",sum[n][5000]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值