zoukankan      html  css  js  c++  java
  • 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-----------------------------------------------------------------------
  • 相关阅读:
    如何运用NLP技巧处理负面情绪
    寻找出路:企业高层面临的困境及对策
    星雨行
    职业发展:从基层到高层的“突破规律”
    老总必看:如何培养自己的“领袖气质”
    成功领导者的“整合性思维”,自己如何培养?
    杨晓芳(帮别人名字作诗)
    别舞动我的情觞
    卖月光
    创业如何找钱:越简单模式越容易成功
  • 原文地址:https://www.cnblogs.com/fenice/p/5848990.html
Copyright © 2011-2022 走看看