• CDOJ ABCDE dp(前缀和优化)


    题目链接:

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

    ABCDE

    Time Limit: 1000/1000MS (Java/Others)
    Memory Limit: 262144/262144KB (Java/Others)
    #### 问题描述 > 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 99. > > For example, in {8,4,2,1}{8,4,2,1} encoding, 11111111 is 1515, exceed 99, so {8,4,2,1}{8,4,2,1} encoding is BCD but not ABCD. In {2,4,2,1}{2,4,2,1} encoding, any number represented by corresponding binary value won't exceed 99, so {2,4,2,1}{2,4,2,1} encoding is ABCD. > > title > > Now, let's talk about ABCDE (Awesome Binary-Coded Decimal Extension). > > An n-ABCDE is such a encoding that can only represent 00 to nn, and every number from 00 to nn can be represented by one or more binary values. So {2,4,2,1}{2,4,2,1} is a 99-ABCDE and {8,4,2,1}{8,4,2,1} is a 1515-ABCDE as we mentioned above. In addition, {16,8,4,2,1}{16,8,4,2,1} is a 3131-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}{2,4,2,1} encoding is the same with the {1,2,2,4}{1,2,2,4} encoding, but it is different from {2,4,4,1}{2,4,4,1}. > > Now, given a number nn, can you tell me how many different nn-ABCDEs? #### 输入 > There is an integer TT in the first line, indicates the number of test cases. > > For each test, the only line contains a integer nn. > > 1≤T≤50001≤T≤5000 > 1≤n≤5000 #### 输出 > For each test, output an integer in one line, which is the number of different nn-ABCDEs. As the answer may be too large, output it modulo (109+7)(109+7) (i.e. if the answer is XX, you should output X % (109+7)X % (109+7)). ####样例输入 > 5 > 1 > 2 > 3 > 4 > 5

    样例输出

    1
    1
    2
    2
    4

    题意

    求子集能够表示1、2、...、n所有数的集合种数。
    比如n=5:{1,1,1,1,1},{1,1,1,2},{1,2,2},{1,1,3}总共4种

    题解

    dp[i][j]表示和为i,且集合里面最大的数为j的总数,则有dp[i][j]=sigma(dp[i-j][k])其中k<=j,j*2-1<=i。 当然这样转移会n3超时,不过我们可以处理出sumv[i][j]=sig(dp[i][k])其中k<=j。然后O(n2)就能跑。

    为什么j*2-1<=i?假设我们已知和为s且满足条件的集合数,那么我们考虑再加一个数x,那么这个数肯定要<=s+1,否则s+1就会无法表示!也就是说如果j能够属于和为i的集合里面的最大数,那么必然就有j+j-1<=i。

    代码

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    const int maxn=5001;
    const int mod=1e9+7;
    
    LL dp[maxn][maxn];
    void pre(){
        clr(dp,0);
        dp[1][1]=1;
        for(int j=1;j<maxn;j++) dp[1][j]=(dp[1][j-1]+dp[1][j])%mod;
        for(int i=2;i<maxn;i++){
            for(int j=1;j*2-1<=i;j++)
                    dp[i][j]=dp[i-j][j];//这里的dp[i-j][j]已经变成是sum[i-j][j]了,但是由于空间比较紧,就没另开
    		//预处理出前缀和。
            for(int j=1;j<maxn;j++)
                    dp[i][j]=(dp[i][j-1]+dp[i][j])%mod;
        }
    }
    
    int main() {
        pre();
        int tc,kase=0;
        scanf("%d",&tc);
        while(tc--){
            int x; scf("%d",&x);
            prf("%lld
    ",dp[x][5000]);
        }
        return 0;
    }
    
    //end-----------------------------------------------------------------------
  • 相关阅读:
    Shell之sed用法 转滴
    再议mysql 主从配置
    CentOS 如何将.deb 文件 转换.rpm
    scp命令[转]
    安装samba服务器
    xdebug影响php运行速度
    PHP中VC6、VC9、TS、NTS版本的区别与用法详解
    将Centos的yum源更换为国内的阿里云源
    centos网卡错误Device eth0 does not seem to be present
    虚拟机VirtualBox中centos6.5网络设置
  • 原文地址:https://www.cnblogs.com/fenice/p/5848990.html
Copyright © 2020-2023  润新知