• [GCJ2017R3]Cooclement


    题目大意:
      一种数列按照如下方式变化:
      新数列第i位等于原数中数字i的出现次数。
      变化过程中数列长度不变。
      例如数列12的变化过程为12-11-20-01-10。
      现在告诉你一个数列x,请求出x可能是有几种数列变化而来的。

    思路:
      将整个变化过程倒过来,除去自环就是一棵树。
      题目就变成了求子树的大小。
      显然枚举一个状态所有的前驱(即树上的子结点)会超时,只有25分。
      然而如果只是求出一个状态对应的后继(父结点)会很简单。
      我们可以枚举出所有的状态,然后求出其后继,最后拓扑排序时DP求出子树大小即可。
      对于一些不存在的状态(各位数之和大于长度),我们则没必要遍历,可以特判判掉。
      如果一个状态的所有前驱都是不存在的,我们可以直接用组合算出它前驱的数量。

      1 #include<queue>
      2 #include<cstdio>
      3 #include<cctype>
      4 #include<ext/hash_map>
      5 int n;
      6 inline int getint() {
      7     register char ch;
      8     n=1;
      9     while(!isdigit(ch=getchar()));
     10     register int x=ch^'0';
     11     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'),n++;
     12     return x;
     13 }
     14 const int N=10;
     15 const int pow[]={1,10,100,1000,10000,100000,1000000,10000000,100000000};
     16 __gnu_cxx::hash_map<int,int> size[N];
     17 inline int fact(const int &n) {
     18     int ret=1;
     19     for(register int i=1;i<=n;i++) {
     20         ret*=i;
     21     }
     22     return ret;
     23 }
     24 inline int comb(const int &n,const int &m) {
     25     return fact(n-m);
     26 }
     27 __gnu_cxx::hash_map<int,int> deg[N];
     28 __gnu_cxx::hash_map<int,int> hash_table[N];
     29 int cnt[N];
     30 int hash(const int &n,const int &x) {
     31     if(hash_table[n].count(x)) return hash_table[n][x];
     32     return hash_table[n][x]=++cnt[n];
     33 }
     34 int nxt[N][50000];
     35 inline void add_edge(const int &n,const int &u,const int &v) {
     36     nxt[n][hash(n,u)]=hash(n,v);
     37     deg[n][hash(n,v)]++;
     38 }
     39 void dfs2(const int now,const int &n) {
     40     int next=0,tmp=now;
     41     while(tmp) {
     42         next+=tmp%10?pow[n-tmp%10]:0;
     43         tmp/=10;
     44     }
     45     if(next==now) {
     46         size[n][now]--;
     47         return;
     48     }
     49     add_edge(n,now,next);
     50 }
     51 void dfs(const int cur,const int &n,const int now,const int sum) {
     52     if(sum>n) return;
     53     if(cur==n) {
     54         if(!sum||size[n].count(hash(n,now))) return;
     55         int &ans=size[n][hash(n,now)];
     56         int nn=n,num=now;
     57         ans=fact(nn);
     58         while(num) {
     59             ans/=fact(num%10);
     60             nn-=num%10;
     61             num/=10;
     62         }
     63         ans/=fact(nn);
     64         ans++;
     65         dfs2(now,n);
     66         return;
     67     }
     68     for(int i=0;i<=n;i++) {
     69         dfs(cur+1,n,(((now<<2)+now)<<1)+i,sum+i);
     70     }
     71 }
     72 int main() {
     73     int T=getint();
     74     for(register int i=1;i<=T;i++) {
     75         const int x=getint();
     76         int tmp=x,sum=0;
     77         while(tmp) {
     78             sum+=tmp%10;
     79             tmp/=10;
     80         }
     81         if(sum>n) {
     82             printf("Case #%d: %d
    ",i,1);
     83             continue;
     84         }
     85         if(size[n].empty()) {
     86             dfs(0,n,0,0);
     87             std::queue<int> q;
     88             for(register int j=1;j<=cnt[n];j++) {
     89                 if(!deg[n][j]) {
     90                     q.push(j);
     91                 } else {
     92                     size[n][j]=1;
     93                 }
     94             }
     95             while(!q.empty()) {
     96                 const int x=q.front();
     97                 q.pop();
     98                 size[n][nxt[n][x]]+=size[n][x];
     99                 if(!--deg[n][nxt[n][x]]) q.push(nxt[n][x]);
    100             }
    101         } 
    102         printf("Case #%d: %d
    ",i,size[n][hash(n,x)]);
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    GBDT(MART)
    C#中数组中Skip、Take和Concat的用法
    VUE中对获取到的数组进行排序
    el-date-picker只能选择今天
    Vue获取时间
    执行Add-Migration Initial报错
    Vue中使用for循环绑定值
    Element UI——日期时间选择器el-date-picker开始时间与结束时间约束解决方案
    el-date-picker日期组件
    缓存的问题
  • 原文地址:https://www.cnblogs.com/skylee03/p/7637489.html
Copyright © 2020-2023  润新知