• PossibleOrders TopCoder


    传送门

    分析

    先用并查集将所有相等元素连为一个,得到不同的元素共cnt种,之后我们的任务便转化为将这些元素分为k组(k≤cnt),所以我们不难得出dp式:dpij=dpi-1j-1*j+dpi-1j*j

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define sp cout<<"---------------------------------------------------"<<endl;
    long long dp[50][50];int cnt,fa[1000];
    class PossibleOrders{
          public:
              int sf(int x){return fa[x]==x?x:fa[x]=sf(fa[x]);}
              void work(string s){
                  int i,k=0,x=0,y=0,n=s.length();
                  for(i=0;i<n;i++)
                    if(s[i]=='=')k++;
                      else if(!k)x=(x<<3)+(x<<1)+(s[i]-'0');
                      else y=(y<<3)+(y<<1)+(s[i]-'0');
                  if(sf(x)!=sf(y)){
                      cnt--;
                      fa[sf(x)]=sf(y);
                  }
                  return;
              }
              long long howMany(int num,vector<string>facts){
                  int i,j,n=num;
                long long ans=0;
                cnt=n;
                for(i=0;i<n;i++)fa[i]=i;
                for(i=0;i<facts.size();i++)work(facts[i]);
                  for(i=1;i<=n;i++)
                  for(j=1;j<=n;j++)
                    dp[i][j]=0;
                dp[0][0]=1;
                  for(i=1;i<=cnt;i++)
                  for(j=1;j<=cnt;j++)
                      dp[i][j]=dp[i-1][j-1]*j+dp[i-1][j]*j;
                  for(i=1;i<=cnt;i++)ans+=dp[cnt][i];
                  return ans;
              }
    };

     

  • 相关阅读:
    团队冲刺第三天
    NoSQL数据库基础概述
    团队开发冲刺第九天
    团队开发冲刺第八天
    团队开发冲刺第七天
    团队开发冲刺第六天
    团队开发冲刺第五天
    团队开发冲刺第四天
    团队开发冲刺第三天
    第九周总结
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9293312.html
Copyright © 2020-2023  润新知