zoukankan      html  css  js  c++  java
  • [hiho1159] Poker

    题意:给你一副扑克中的几张牌,要你将这些牌进行排列,并且相邻的牌数字不能相同

    题解:

    dp(组合数)

    dp[i][j]表示放到第i种数字,有j个数字相同且相邻的方案数

    1、对于同一种数字,可以将其划分为k组,有C(cnt[i]-1,k-1)种分法

    2、考虑将这k组中的l组放到数字相同的中间,其余放置任意位置,则分别有:

    C(j,l)和C(tot+1-j,k-l)种放法(tot表示前面有多少张牌)

    那么就可已转移了

    设x为放完后的同花色相邻,则x=j+a[i]-k-l

    dp[i][x]+=C(j,l) * C(tot+1-j,k-l)* C(cnt[i]-1,k-1) * dp[i-1][j]

    /*
      Poker
      组合dp
    */
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ull unsigned long long 
    using namespace std;
    
    int num[310],cnt[15];
    ull c[55][55],dp[15][55],fac[10];
    char alph[15]={"0A23456789TJQK"};
    
    int gi() {
      int x=0,o=1; char ch=getchar();
      while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
      if(ch=='-') o=-1,ch=getchar();
      while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
      return o*x;
    }
    
    void pre() {
      c[0][0]=1;
      for(int i=1; i<=52; i++) {
        c[i][0]=c[i][i]=1;
        for(int j=1; j<i; j++) {
          c[i][j]=c[i-1][j-1]+c[i-1][j];
        }
      }
      for(int i=1; i<=13; i++) num[alph[i]]=i;
      fac[0]=1;
      for(int i=1; i<=4; i++) fac[i]=fac[i-1]*i;
    }
    
    int main() {
      pre();
      int T=gi(),tot,n,t=0;
      while(T--) {
        n=gi(),tot=0;
        memset(cnt,0,sizeof(cnt));
        for(int i=1; i<=n; i++) {
          char s[3];
          scanf("%s", s);
          cnt[num[s[0]]]++;
        }
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for(int i=1; i<=13; i++) {
          if(cnt[i]==0) {
        for(int j=0; j<=max(0,tot-1); j++)
          dp[i][j]=dp[i-1][j];
        continue;
          }
          for(int j=0; j<=max(0,tot-1); j++) 
        for(int k=1; k<=cnt[i]; k++) 
          for(int l=0; l<=k; l++) 
            if(j+cnt[i]-k-l>=0)
              dp[i][j+cnt[i]-k-l]+=dp[i-1][j]*c[cnt[i]-1][k-1]*c[j][l]*c[tot+1-j][k-l];
          tot+=cnt[i];
        }
        ull ans=dp[13][0];
        for(int i=1; i<=13; i++) {
          ans=ans*fac[cnt[i]];
        }
        printf("Case #%d: %llu
    ", ++t,ans);
      }
    }
  • 相关阅读:
    KVC与KVO的进阶使用
    Qt之图形视图框架
    Qt之QRoundProgressBar(圆形进度条)
    Qt之绘制闪烁文本
    Qt之QCustomPlot(图形库)
    Qt之事件系统
    iOS 保持界面流畅的技巧
    iOS开发数据库SQLite的使用
    Qt之保持GUI响应
    Qt之QSS(QDarkStyleSheet)
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7593768.html
Copyright © 2011-2022 走看看