zoukankan      html  css  js  c++  java
  • 2019 山东省赛 B 题

    题意

    给你一排 (n) 个灯泡,让你进行 (k) 轮操作,每轮操作可以点亮或熄灭 (m) 个不同的灯泡。然后给你这排灯泡的初态和末态,问你在 (k) 轮操作后能让这排灯泡到达末态的方案有多少种(对 (998244353) 取模)。

    题解

    首先可以发现,终状态与起始状态不同的开关一定被改变了奇数次,反之偶数次。设 ( ext{dp}[i][j]) 表示第 (i) 轮有 (j) 个位置是被改变了奇数次。那么可以发现,假设这次有 (j) 个位置是奇数次,这次有 (k) 个位置从奇数次变成了偶数次,那么很明显,剩下 (m-k) 个位置就是从偶数次变成了奇数次。那么 ( ext{dp}[i+1][j-k+m-k]+= ext{dp}[i][j]cdot C_{j}^{k}cdot C_{n-j}^{m-k}) 这个式子就出来了,也就是下一轮的 (j-k+m-k) (之前有 (j) 个奇数次位,减去了这次变成偶数位的个数 (k),再加上这次由偶数位变成奇数位的个数 (m-k)),这也就是 ( ext{dp}[i][j]) 中的 (j) 个奇数位中选择 (k) 个,从剩下的 (n-j) 个偶数位中选出 (m-k) 个,得到的就是如上的式子。

    这个问题的第二个关键点在于初值的赋值。有两种显而易见的赋值方式,( ext{odd_num}) 指的是两个串中状态不同的位置的个数,一种是开头 ( ext{dp}[0][0]),结束 ( ext{dp}[k][ ext{odd_num}]),也就是刚开始没有奇数位变化的位,最后出现有奇数位变化,还有一种是 ( ext{dp}[0][ ext{odd_num}],\, ext{dp}[n][0]),可以发现只有第二种是正确的,因为第一种到最后只能保证有 ( ext{odd_num}) 个位发生变化,不能保证是哪几个,而如果第二种,就先保证了起始有 (m) 个位需要改变只有一种情况。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define per(i,a,b) for(int i=a;i>=b;i--)
    const int MAXN = 1e2+5;
    const int MOD = 998244353;
    ll dp[MAXN][MAXN];///dp[i][j]表示第i轮有j位是奇数的情况
    ll c[MAXN][MAXN];///组合数
    char s1[MAXN],s2[MAXN];
    int main(){
        rep(i,0,100)c[i][0]=1;
        rep(i,1,100)c[i][i]=1;
        rep(i,2,100){
            rep(j,1,i-1){
                c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD;
            }
        }
        int t,n,k,m;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d%s%s",&n,&k,&m,s1,s2);
            int num=0;
            rep(i,0,n-1){
                if(s1[i]!=s2[i])num++;
            }
            memset(dp,0,sizeof(dp));
            dp[0][num]=1;
            rep(i,0,k-1){
                rep(j,0,n){///之前有j个奇数次变化的位置
                    rep(k,0,m){///有k个奇数变成了偶数
                        if(j>=k&&n-j>=m-k){
                            dp[i+1][j-k+m-k]+=dp[i][j]*c[j][k]%MOD*c[n-j][m-k]%MOD;
                            dp[i+1][j-k+m-k]%=MOD;
                        }
                    }
                }
            }
            printf("%lld
    ",dp[k][0]);
        }
        return 0;
    }
    
  • 相关阅读:
    sqlParameter的两种写法 以及存储过程还有sql语句(防注入)
    SqlServer2005 SQL Server 版本变更检查 警告
    禁用自带防火墙
    sql分页
    每个程序员都必须遵守的编程原则
    在PDA设备上安装SQL Server Compact
    Mcrosoft SQL Server 自定义函数
    程序员人生之路(转)
    在windows 7 上为 sqlserver 2008 启用远程访问
    在PDA设备上安装和部署 SQL Server Compac 3.5(官方版)
  • 原文地址:https://www.cnblogs.com/DariusOrz/p/13768046.html
Copyright © 2011-2022 走看看