zoukankan      html  css  js  c++  java
  • 7.19T1

    现在的我是T2一点头绪都搞不到(然而大家都快要A掉它了,我还处在M0的状态),T3只能摸到个大体思路,但是还是模模糊糊的,决定写点题解,冷静一下

    通过T1部分分式子的过程,让我意识到对于一道明确的DP题,一定要在算草纸上写一写,推一推,你可以列出来你有什么,你需要什么,然后去依据DP的实际意义进行拼凑,当然对自己DP式子的不断优化也是需要的

    30分其实很好拿,我们设定$dp[i][j]$代表到第$i$天还剩下$j$块饼干没有被分出去,那么这个$i$应该属于$[1,d]$,那很容易可以想到$dp[i][j]+={sum}dp[i-1][k]$,$k$属于$[j,j+m-1]$,那应该在优化时可以想到这个$sum$可以用前缀和搞定,关于初始化令$dp[0][n]=1$然后处理一下前缀和就可以了

    但实际上我们很容易就能够看出这个想法的不足之处,比如你的第一维要循环$d$,不论时间会不会炸,空间一定是炸了,并且是根本开不到的那种,但是你会发现$n$其实算的上很小,而且对于$d$远大于$n$的情况,一定是有很多天都没有给饼干,那我们完全就可以把这些什么都没有给出的天从$dp$中除名,这样的话空间,时间复杂度都可以降下来很多,那我们就重新来定义$dp[i][j]$的含义,我们用$dp[i][j]$来表示,已经给出去饼干$i$天(给出去饼干就代表饼干数不为0),一共给出去$j$块饼干,我们模仿着刚才的思路,依旧可以写出来一个前缀和优化过的DP式子,$dp[i][j]=sum[i-1][j]-sum[i-1][j-m]$,其实这个东西是在可想的范围内的,但是我没想啊,那能有什么办法,怪自己呗

    关于这个$sum[i-1][j-m]$一定要注意一下$j-m$是不是小于0了,最好还是不要下标越界,关于取模,只要你对自己的时间复杂度足够自信,那你就随便模,如果有做减法的情况,一定要先加一个模数,免得出现负数,在这里在给一个小建议,如果不知道自己会不会得到什么奇奇怪怪的负数,那就自己去造几组比较大的数据,没有暴力的话,没办法看对错,但是如果出现负数了,证明你肯定不对

    最后的$ans={sum}dp[i][n]{ imes}C_d^i$,在我们对$C$进行计算的时候会发现不论是$Lucas$还是杨辉三角打表,下标为$d$都不是可用的好方法,那我们思考一下$C_n^m=frac{n!}{m!{ imes}(n-m)!}$,我们进行一下简单的消项,那$C_n^m=frac{n{ imes}(n-1){ imes}{cdots}{ imes}(n-m+1)}{m!}$,那对于分母上m!我们可以求一下逆元,对于分子那一大坨,因为$i$每次之加一,完全可以递推$O(1)$实现,这样的话我们不仅解决了这道题,还得到了一个求C的新思路

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define ll long long
     5 #define maxn 2010
     6 using namespace std;
     7 const long long mod=998244353;
     8 int n,m;
     9 ll d,ans;
    10 ll jc[maxn],ny[maxn];
    11 ll dp[maxn][maxn],sum[maxn][maxn];
    12 ll ksm(ll a,ll b)
    13 {
    14     ll ans=1;  a=a%mod;
    15     while(b>0)
    16     {
    17         if(b&1)  ans=(ans*a)%mod;
    18         b=b>>1;  a=(a*a)%mod;
    19     }
    20     return ans%mod;
    21 }
    22 void clear()
    23 {
    24     memset(dp,0,sizeof(dp));  memset(sum,0,sizeof(sum));
    25     memset(jc,0,sizeof(jc));  memset(ny,0,sizeof(ny));
    26     ans=0;  dp[0][0]=1;  jc[0]=1;
    27     for(int i=0;i<=n;++i)  sum[0][i]=1;
    28     for(int i=1;i<=n;++i)  jc[i]=(jc[i-1]*i)%mod;
    29     ny[n]=ksm(jc[n],mod-2);
    30     for(int i=n;i>=1;--i)  ny[i-1]=(ny[i]*i)%mod;
    31 }
    32 int main()
    33 {
    34     while(1)
    35     {
    36         scanf("%d%lld%d",&n,&d,&m);
    37         if(n==0&&d==0&&m==0)  break;
    38         if(d*(ll)m<(ll)n)  {printf("0
    ");  continue;}
    39         clear();
    40         for(int i=1;i<=min((ll)n,d);++i)
    41         {
    42             for(int j=i;j<=n;++j)
    43             {
    44                 if(j-m<0)
    45                 {
    46 //                    cout<<"j-m="<<j-m<<endl;
    47 //                    cout<<"sum["<<i-1<<"]["<<j-1<<"]="<<sum[i-1][j-1]<<" ";
    48                     dp[i][j]=sum[i-1][j-1];
    49 //                    cout<<"dp["<<i<<"]["<<j<<"]=sum["<<i-1<<"]["<<j-1<<"]"<<" ";
    50 //                    if(dp[i][j]<0)  cout<<"dp["<<i<<"]["<<j<<"]="<<dp[i][j]<<endl;
    51                 }
    52                 else
    53                 {
    54 //                    cout<<"sum["<<i-1<<"]["<<j-1<<"]="<<sum[i-1][j-1]<<" ";
    55 //                    cout<<"sum["<<i-1<<"]["<<j-m<<"]="<<sum[i-1][j-m]<<" ";
    56                     dp[i][j]=(sum[i-1][j-1]-sum[i-1][j-m]+mod)%mod;
    57 //                    cout<<"dp["<<i<<"]["<<j<<"]=sum["<<i-1<<"]["<<j-1<<"]-";
    58 //                    cout<<"sum["<<i-1<<"]["<<j-m<<"]"<<" ";
    59 //                    if(dp[i][j]<0)  cout<<"dp["<<i<<"]["<<j<<"]="<<dp[i][j]<<endl;
    60                 }
    61                 sum[i][j]=(sum[i][j-1]+dp[i][j])%mod;
    62 //                if(sum[i][j]<0)  cout<<"sum["<<i<<"]["<<j<<"]="<<sum[i][j]<<endl;
    63             }
    64         }
    65         ll ls=d%mod;
    66         for(int i=1;i<=min((ll)n,d);++i)
    67         {
    68             ll zhs=ny[i];
    69             if(i!=1)  ls=(ls*(d%mod-(ll)i+(ll)1)%mod)%mod;
    70             zhs=(zhs*ls)%mod;
    71 //            for(int j=d-i+1;j<=d;++j)  zhs=(zhs*j)%mod;
    72 //            cout<<"C("<<d<<","<<i<<")="<<zhs<<endl;
    73             ans=(ans+(dp[i][n]*zhs)%mod)%mod;
    74 //            if(ls<0)  cout<<ls<<endl;
    75         }
    76 //        for(int i=1;i<=min((ll)n,d);++i)
    77 //            for(int j=0;j<=n;++j)  cout<<"dp["<<i<<"]["<<j<<"]="<<dp[i][j]<<endl;
    78 //        for(int i=1;i<=((ll)n,d);++i)
    79 //            for(int j=0;j<=n;++j)  cout<<"sum["<<i<<"]["<<j<<"]="<<sum[i][j]<<endl;
    80 //        while(ans<0)  ans=ans+mod;
    81         printf("%lld
    ",ans%mod);
    82     }
    83     return 0;
    84 }
    调试略显丑陋
  • 相关阅读:
    DJango xadmin 表头和标底设置,显示隐藏和显示
    xadmin 无法创建xadmin_log 或者是xadmin源代码使用,没有引用xadmin包报错或 1146, "Table 'mxonline.xadmin_log' doesn't exist"
    No module named import_export.admin Django python
    Django 创建超级管理员失败
    燕十八redis 微博地址
    Mysql数据库表的自增主键ID号乱了,需要重新排列。
    SQL 语句实例
    MYSQL修改表结构
    将sqlserver中的表复制到mysql
    MySQl查询语句大全
  • 原文地址:https://www.cnblogs.com/hzjuruo/p/11219416.html
Copyright © 2011-2022 走看看