• 6833. 2020.10.24【NOIP提高A组】T3.justice


    Solution

    首先 x=y 时答案肯定为 1,然后讨论 x≠y 的情况。

    其实可以直接把 x,y当成 1,0,因为最终合并成一个细胞,相当于在每个x,y前配个 (1/k)

    使所有系数和为 1 ,求某些限制下,x 前的系数和不同的方案数。

    那么先单单看 x ,我们把系数和看成在 k 进制下的小于 1 的小数 ( 设为 p ) ,

    对于每个 x 前的 (1/k)的系数,相当于在对应的小数位上加 1 ,

    假若不存在进位,那么限制就是每个数位上的和 ( 设为s ) = n,

    如果有进位,每进一位相当于将 s - ( k - 1 ) ,所以就要使 ∑c ≡ m (mod (k − 1 ) ),

    那么再看 y ,就是要使系数和= 1 - p ( 那个小数 ),

    假设小数有 len 位,那么 1 − p 的和 应为 (len − 1)(k − 1) + k − s = len(k − 1) − s + 1。

    那么就可以设 f [ i ] [ j ] 表示到第 i 位,目前和为 j 的方案数即可,因为末尾不能为 0,所以要多开一维记一下最后一位是否为 0。

    Code

    #include<cstdio>
    #define ll long long
    using namespace std;
    
    const int N=3010,mo=1e9+7;
    int f[N][N][2];
    int n,m,k,i,j,l,an; ll x,y;
    
    int main(){
        freopen("justice.in","r",stdin);
        freopen("justice.out","w",stdout);
        scanf("%d%d%d%lld%lld",&n,&m,&k,&x,&y);
        if (x==y){printf("1"); return 0;}
        f[0][0][1]=1;
        for(i=1;i<=(n+m-1)/(k-1);++i){
            for(j=0;j<=n;++j){
                for(l=1;l<k;++l)
                    if (j-l>=0) f[i][j][0]=(1ll*f[i][j][0]+f[i-1][j-l][0]+f[i-1][j-l][1])%mo;
                f[i][j][1]=(1ll*f[i][j][1]+f[i-1][j][1]+f[i-1][j][0])%mo;
                if (j%(k-1)==n%(k-1)&&(i*(k-1)-j+1)<=m&&(i*(k-1)-j+1)%(k-1)==m%(k-1)) an=(an+f[i][j][0])%mo;
            }
        }
        printf("%d",an);
        return 0;
    }
  • 相关阅读:
    LightningChartJS2.0即将火热推出,敬请期待!
    html转word
    Windows上使用Python2.7安装pip
    人工智能?.netcore一样胜任!
    远程浏览服务器上的文件
    C# winform间窗体传值简单Demo
    C#发送QQ邮箱
    各种文件用JS转Base64之后的data类型
    当你的VS2019没法自动补全了,或者自动补全按回车直接换行的时候
    easyUI filebox 获取文件对象
  • 原文地址:https://www.cnblogs.com/zsjz-yzy/p/13871268.html
Copyright © 2020-2023  润新知