zoukankan      html  css  js  c++  java
  • 【u128】又一个数字游戏

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    小明拿出了一个素数集合,{2, 3, 5, 7, 11, 13, …, 127, …},他发现,从小到大排序后,127是第31个数,而31也在素数集内,31是第
    11个数,11是第5个数,5是第3个数,3是第2个数,2是第1个数。
    而127,31,11,5,3,2都为素数。
    这时,小明又发明了一个游戏,给出一个n,取出一个{2, 3, 4, …, n}的一个子集,子集中必须包含n。将取出子集中的数从小到大排序后
    ,他先取出n,n是第k1大的数,再取出k1,k1是第k2大的数,再取出k2……这样不断下去,最后能取出最小的数。对于给定的n,为{2, 3,
    4, …, n}的子集中有多少个满足要求。

    【输入格式】

    输入文件another.in的第一行包含一个正整数T,表示了数据组数。
    接下来T行,每行一个不小于2的正整数n,如题目所述。
    【输出格式】

    输出文件another.out包括T行,对于每个n输出相应答案,由于答案可能很大,你需要输出答案mod 100003后的结果,请注意可能要使用
    int64或者long long。

    【数据规模】

    对于20%的数据,有T≤5, N≤12; 对于60%的数据,有T≤50,N≤100; 对于100%的数据,有T≤500,N≤500。

    Sample Input1

    2
    5
    6

    Sample Output1

    5
    8

    【样例说明】

    对于n=5,有以下5个答案:

    {5}, {2, 5}, {2, 3, 5}, {2, 3, 4, 5}, {3, 4, 5}

    {2, 4, 5}不行是因为5是第3大的数,3不在集合中。

    {3, 5}同样也不行,因为5是第2大的数,2不在集合中。

    对于n = 6

    {3, 4, 5, 6}不行是因为6是第4大的数,4是第2大的数,2不在集合中。

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u128

    【题意】

    【题解】

    设f[i][j]表示最大的数为i,然后最大的数的位置在j的方案数;
    则f[i][j] = ∑(f[j][k]*C(i-j-1,j-k-1);
    这里本来i是第j大的(因为在第j个位置),然后按照游戏的规则
    前一个就是数字j了,
    这正好和状态f[j][k]对应;
    即最大的数字为j,然后j的位置在k;
    这里k和j之间有k-j-1个空位;
    你可以在这k-j-1个空位里面放j+1..i-1这些数字;组合数嘛;
    预处理一下组合数就好;
    这里抓住了游戏的前一个和后一个数字的矛盾,用来当做状态.
    很优秀。
    最后累加f[n][1..n-1]就好;
    边界f[2][1]=1;

    【完整代码】

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <iostream>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%lld",&x)
    #define ref(x) scanf("%lf",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int N = 500+10;
    const LL MOD = 100003;//少加了个0........QAQ
    
    LL c[N][N],f[N][N],sum[N];
    
    void pre_zuhe()
    {
        c[0][0] = 1;
        rep1(i,1,500)
            c[i][0] = c[i][i] = 1;
        rep1(i,2,500)
            rep1(j,1,i-1)
                c[i][j] = (c[i-1][j-1]+c[i-1][j])%MOD;
        //cout << c[4][3]<<endl;
    }
    
    void do_dp()
    {
        f[2][1] = sum[2] = 1;
        rep1(i,3,500)//最大数字为i
        {
            f[i][1] = f[i][2] = 1;sum[i] = 2;
            rep1(j,3,i-1)//位置在j
            {
                rep1(k,1,j-1)//往前一个,最大数字为j,然后位置在k
                    if (i-j-1>=j-k-1)
                        f[i][j]=(f[i][j]+f[j][k]*c[i-j-1][j-k-1])%MOD;
                sum[i] = (sum[i]+f[i][j])%MOD;
            }
        }
    }
    
    void o()
    {
        int T;
        rei(T);
        while (T--)
        {
            int n;
            rei(n);
            cout << sum[n] << endl;
        }
    }
    
    int main()
    {
       // freopen("F:\rush.txt","r",stdin);
        pre_zuhe();//ok
        do_dp();//ok
        o();//ok
        //printf("
    %.2lf sec 
    ", (double)clock() / CLOCKS_PER_SEC);
        return 0;
    }
  • 相关阅读:
    python--数据可视化
    python--数据处理与探索
    如何使用.NET开发全版本支持的Outlook插件产品(四)——进阶探讨
    如何使用.NET开发全版本支持的Outlook插件产品(三)——全面控制
    对于.NET Socket连接的细节记录
    如何使用.NET开发全版本支持的Outlook插件产品(二)——完善插件
    如何使用.NET开发全版本支持的Outlook插件产品(一)——准备工作
    不建议双挖
    不要挖门罗
    关于PoW工作量证明的不公平
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626519.html
Copyright © 2011-2022 走看看