zoukankan      html  css  js  c++  java
  • AGC002 F Leftmost Ball——DP

    题目:https://atcoder.jp/contests/agc002/tasks/agc002_f

    充要条件是前缀0的个数 >= 颜色种数。

    设计 DP ,放一个颜色的时候就把所有该颜色的点都考虑完,不要一个一个放。这样就不用考虑 “剩下多少个旧颜色的点可用” 了。

    新放一种颜色的时候,知道现在已经填了多少个位置,所以所有该颜色点的放置方案数是可算的。

    dp[ i ][ j ] 表示放了 i 个 0 、j 种颜色的方案。认为颜色是按顺序放的,最后乘上阶乘。就有 ( dp[i][j] -> dp[i+1][j] , dp[i][j]*inom{(n-j)(k-1)+n-i-1}{k-2} -> dp[i][j+1] ) 。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=2005,M=N*N,mod=1e9+7;
    int upt(int x)
    {while(x>=mod)x-=mod;while(x<0)x+=mod;return x;}
    int pw(int x,int k)
    {int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;}
    
    int n,k,jc[M],jcn[M],dp[N][N];
    void init()
    {
      int lm=n*k;
      jc[0]=1;for(int i=1;i<=lm;i++)jc[i]=(ll)jc[i-1]*i%mod;
      jcn[lm]=pw(jc[lm],mod-2);
      for(int i=lm-1;i>=0;i--)jcn[i]=(ll)jcn[i+1]*(i+1)%mod;
    }
    int C(int n,int m)
    {
      if(n<0||m<0||n<m)return 0;
      return (ll)jc[n]*jcn[m]%mod*jcn[n-m]%mod;
    }
    int main()
    {
      scanf("%d%d",&n,&k); if(k==1){puts("1");return 0;}
      init();
      dp[0][0]=1;
      for(int i=0;i<=n;i++)
        for(int j=0;j<=i;j++)
          {
        if(!dp[i][j])continue;int tp=dp[i][j];
        if(i<n)dp[i+1][j]=upt(dp[i+1][j]+tp);
        if(j<i)
          {
            int ml=C((n-j)*(k-1)+n-i-1,k-2);
            dp[i][j+1]=(dp[i][j+1]+(ll)ml*tp)%mod;
          }
          }
      printf("%lld
    ",(ll)dp[n][n]*jc[n]%mod);
      return 0;
    }
  • 相关阅读:
    Makefile中的函数
    Android命令行工具使用总结
    功耗杂项笔记汇总
    Repo学习笔记
    CPU调度——EAS调度器
    Android log常用分析方法
    event log 分析
    用户空间控制驱动与设备的绑定与解绑
    内核工具 – Sparse 简介
    在docker宿主机上查找指定容器内运行的所有进程的PID
  • 原文地址:https://www.cnblogs.com/Narh/p/11003737.html
Copyright © 2011-2022 走看看