• B1072 [SCOI2007]排列perm 状压dp


    很简单的状压dp,但是有一个事,就是。。。我数组开大了一点,然后每次memset就会T,然后开小就好了!!!震惊!以后小心点这个问题。

    题干:

    Description
    
      给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0)。例如123434有90种排列能
    被2整除,其中末位为2的有30种,末位为4的有60种。
    Input
    
      输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开。s保证只包含数字0, 1
    , 2, 3, 4, 5, 6, 7, 8, 9.
    Output
      每个数据仅一行,表示能被d整除的排列的个数。
    Sample Input
    7
    000 1
    001 1
    1234567890 1
    123434 2
    1234 7
    12345 17
    12345678 29
    Sample Output
    1
    3
    3628800
    90
    3
    6
    1398
    HINT
    在前三个例子中,排列分别有1, 3, 3628800种,它们都是1的倍数。
    【限制】
    100%的数据满足:s的长度不超过10, 1<=d<=1000, 1<=T<=15
    Source

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    char s[20];
    int t;
    ll d;
    ll dp[1 << 12][1003];
    ll num[20],p[20];
    int main()
    {
        read(t);
        while(t--)
        {
            clean(dp);clean(num);clean(p);
            scanf("%s",s + 1);
            int l = strlen(s + 1);
    //        cout<<l<<endl;
            duke(i,1,l)
            num[s[i] - '0']++,p[i] = s[i] - '0';
            read(d);
            dp[0][0] = 1;        
            duke(i,0,(1 << l) - 1)
            {
                duke(j,0,d - 1)
                {
                    duke(k,1,l)
                    {
                        if((i & (1 << (k - 1))) == 0)
                        {
                            dp[i | (1 << (k - 1))][(j * 10 + p[k]) % d] += dp[i][j];
                        }
                    }
                }
            }
    //        cout<<"QAQ"<<endl;
            ll ans = dp[(1 << l) - 1][0]; 
            duke(i,0,9)
            {
                duke(j,1,num[i])
                ans /= j;
            }
            printf("%lld
    ",ans); 
        }
        return 0; 
    } 
    /*
    7
    000 1
    001 1
    1234567890 1
    123434 2
    1234 7
    12345 17
    12345678 29
    */
  • 相关阅读:
    php 框架选择
    转:从框架看PHP的五种境界及各自的薪资待遇(仅限于二三线城市,一线除外)
    百度云怎样提升下载速度
    .net体系与java体系
    绘制3D的js库
    Canvas游戏计算机图形教程
    Unity Manual 用户手册
    在windows系统下安装oracle 11g
    Three.js学习笔记
    php面试题之二——数据结构和算法(高级部分)
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9749027.html
Copyright © 2020-2023  润新知