zoukankan      html  css  js  c++  java
  • bzoj 1072: [SCOI2007]排列perm

    Description

      给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0)。例如123434有90种排列能
    被2整除,其中末位为2的有30种,末位为4的有60种。

    solutio

    这题复杂负很诡,爆搜可以过去
    我写的状压DP,复杂度和搜索一样,(O(10!*10*d* T))
    设状态为 (f[i][j]) 表示已经选了序列中的位置状态为 (i) ,mod d等于 (j) 的方案数
    转移运用读入优化的方法,直接 (*10+a[i]) 取模就行

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=15;
    int f[1<<10][1005],t[15],mul[N];char s[N];
    void work()
    {
       scanf("%s",s);
       int n=strlen(s),d;
       int lim=(1<<n)-1;
       RG int i,j,k;
       scanf("%d",&d);
       f[0][0]=1;
       for(i=0;i<lim;i++){
          for(j=0;j<d;j++){
             if(!f[i][j])continue;
             for(k=0;k<n;k++){
                if((1<<k)&i)continue;
                f[i|(1<<k)][(j*10+s[k]-48)%d]+=f[i][j];
             }
          }
       }
       for(i=0;i<n;i++)t[s[i]-48]++;
       for(i=0;i<=9;i++)if(t[i])f[lim][0]/=mul[t[i]],t[i]=0;
       printf("%d
    ",f[lim][0]);
       memset(f,0,sizeof(f));
    }
     
    int main()
    {
        int T;cin>>T;
       mul[0]=1;for(int i=1;i<=10;i++)mul[i]=mul[i-1]*i;
       while(T--)work();
        return 0;
    }
    
    
  • 相关阅读:
    js动态获取地址栏后的参数
    html页面保存数的两种方式
    微信开发之八 页面获取周围beacon设备
    【摄影】田子坊
    最好的时光在路上,最美的风景在远方
    【前端统计图】echarts实现简单柱状图
    js实现计时功能
    luogu 电车
    cogs luogu 砍树
    cogs 通往奥格瑞玛的道路 WD
  • 原文地址:https://www.cnblogs.com/Hxymmm/p/7728205.html
Copyright © 2011-2022 走看看