AGC005D : ~K Perm Counting(容斥)

传送门

题解:
容斥,记 fi f i 表示有 i i 个位置不满足的方案数,那么答案为i=0n(1)ifi

\mathchoicemodk \mathchoice mod k 意义下,相同的位置做 DP D P ,最后再背包合并即可得到 fi f i

#include <bits/stdc++.h>
using namespace std;
const int N=2e3+50,mod=924844033;
int n,k,dp[N][N][4],f[2][N],fac[N],ans;
inline int add(int x,int y) {return (x+y>=mod)?x+y-mod:x+y;}
inline int mul(int x,int y) {return (long long)x*y%mod;}
int main() {
    cin>>n>>k; fac[0]=1;
    for(int i=1;i<=n;i++) fac[i]=mul(fac[i-1],i);
    for(int i=1;i<=n;i++) {
        if(i<=k) {
            dp[i][0][0]=1;
            if(i+k<=n) dp[i][1][2]=1;
        } else {
            for(int j=0;j<=i && j<=n;j++) {
                for(int s=0;s<=3;++s) 
                    dp[i][j][s>>1]=add(dp[i][j][s>>1],dp[i-k][j][s]);
                if(!j) continue;
                dp[i][j][0]=add(dp[i][j][0],dp[i-k][j-1][0]);
                dp[i][j][1]=add(dp[i][j][1],dp[i-k][j-1][2]);
                if(i+k<=n) {
                    dp[i][j][2]=add(dp[i][j][2],dp[i-k][j-1][0]);
                    dp[i][j][2]=add(dp[i][j][2],dp[i-k][j-1][1]);
                    dp[i][j][3]=add(dp[i][j][3],dp[i-k][j-1][2]);
                    dp[i][j][3]=add(dp[i][j][3],dp[i-k][j-1][3]);       
                }
            }
        }
    }
    int now=0; f[now][0]=1;
    for(int i=n;i>n-k && i;i--) {
        now^=1;
        for(int j=0;j<=n;j++) f[now][j]=0;
        for(int j=0;j<=n/k+1;++j) {
            int rs=0;
            for(int s=0;s<=3;s++) rs=add(rs,dp[i][j][s]);
            if(!rs) continue;
            for(int k=n;k>=j;k--)
                f[now][k]=add(f[now][k],mul(f[now^1][k-j],rs));
        }
    }
    for(int i=0;i<=n;i++) {
        if(i&1) ans=add(ans,mod-mul(f[now][i],fac[n-i]));
        else ans=add(ans,mul(f[now][i],fac[n-i]));
    }
    printf("%d\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值