题面

传送门

思路

首先可以明确的一点是,本题中出现不满足条件的所有的数,都是分组的

只有模$K$意义下相同的数之间才会出现不满足条件的情况,而且仅出现在相邻的情况

那么我们考虑把这个性质利用起来

我们单独把其中一组抽出来考虑:设这一组为$p,p+k,p+2k,p+3k.....$

那么我们发现,这其中每两个相邻的数之间都是互相不能选的

但是要注意,我们本题中讨论的实际上更应该是位置的关系,所以此时就变成了这样的形式:

位置$p+ki$不能选数$p+k(i+1)$,位置$p+ki(i+1)$不能选数$p+ki$

也就是说这两条边是交叉的

我们考虑对于每个值构建两个点,一个代表顺序为这个值的位置,一个代表这个数

那么上述的同一组的数中,我们连接不能同时选的数和位置,可以构造出两条链:

数$p$---位置$p+k$---数$p+2k$---位置$p+3k$......

位置$p$---数$p+k$---位置$p+2k$---数$p+3k$......

这两条链上的选择又是互相独立的

于是,我们把一个链单独拿出来考虑

显然这个链上选择了几条边,就有几个点是不满足要求的

那么我们可以通过一个$dp[i][j][0/1]$表示前$i$个点选了$j$条边,目前最后一条边选了没有(因为这里不能两条相邻的边同时选),来推出这条链选每一个数量的边的方案数量

(方程参见代码)

同时本题中有一个显然的组合容斥:

设$ans$为答案,那么$ans=\sum_{i=0}^n method(i)(-1)^i (n-i)!$,其中$method(i)$表示选$i$条边的方案数

那么我们只要把所有的链拼起来(不同的链的连接位置强制不能选边),然后跑$dp$算答案就可以了

感觉讲的不是很清楚......具体可以参考代码的注释

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<cmath>
#define ll long long
#define MOD 924844033
using namespace std;
inline int read(){
int re=0,flag=1;char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') flag=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
int n,k;
ll dp[4010][2010][2],border[4010],f[2010],fac[2010];
int main(){
n=read();k=read();int i,j,re=n%k;ll tmp=0,ans=0;
fac[0]=fac[1]=1;
for(i=2;i<=n;i++) fac[i]=fac[i-1]*i%MOD;
for(i=1;i<=re;i++){//这两个循环是把链拆出来,标记哪个地方是断点
tmp+=(n/k+1);border[tmp]=1;
tmp+=(n/k+1);border[tmp]=1;
}
for(i=re+1;i<=k;i++){
tmp+=n/k;border[tmp]=1;
tmp+=n/k;border[tmp]=1;
}
dp[1][0][0]=1;
for(i=2;i<=(n<<1);i++){
for(j=0;j<=n;j++){
dp[i][j][0]=(dp[i-1][j][0]+dp[i-1][j][1])%MOD;
if(!border[i-1]) dp[i][j][1]=dp[i-1][j-1][0];
//这里是dp方程
}
}
for(i=0;i<=n;i++) f[i]=(dp[n<<1][i][0]+dp[n<<1][i][1])%MOD;
tmp=1;
for(i=0;i<=n;i++){//容斥
ans+=tmp*f[i]*fac[n-i]%MOD;ans=(ans+MOD)%MOD;
tmp=-tmp;
}
printf("%lld\n",ans);
}

[AGC005D] ~K Perm Counting [dp]的更多相关文章

  1. [Agc005D]K Perm Counting

    [Agc005D] K Perm Counting Description 糟糕爷特别喜爱排列.他正在构造一个长度为N的排列.但是他特别讨厌正整数K.因此他认为一个排列很糟糕,当且仅当存在至少一个i( ...

  2. AGC 005 D - ~K Perm Counting

    D - ~K Perm Counting 链接 题意: 求有多少排列对于每个位置i都满足$|ai−i|!=k$.n<=2000 分析: 容斥+dp. $answer = \sum\limits_ ...

  3. AGC 005D.~K Perm Counting(容斥 DP 二分图)

    题目链接 \(Description\) 给定\(n,k\),求 满足对于所有\(i\),\(|a_i-i|\neq k\)的排列的个数. \(2\leq n\leq 2000,\quad 1\leq ...

  4. 【agc005d】~K Perm Counting

    题目大意 求有多少中1~n的排列,使得\(abs(第i个位置的值-i)!=k\) 解题思路 考虑容斥,\(ans=\sum_{i=0}^{n}(-1)^ig[i](n-i)!(g[i]表示至少有i个位 ...

  5. [AT2062] ~K Perm Counting

    AT2602 , Luogu 求对于 \(n\) 个数的排列 , 有多少种方案满足对于所有的 \(i\) , \(|P_i - i| != K\) , 答案对 \(924844033\) 取模 . \ ...

  6. 题解-Atcoder_agc005D ~K Perm Counting

    Problem AtCoder-agc005D 题意概要:给出\(n,k\),求合法的排列个数,其中合法定义为任何数字所在位置与自身值差的绝对值不为\(k\)(即求排列\(\{A_i\}\),使得\( ...

  7. 蓝桥杯试题 k倍区间(dp)

    问题描述 给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间. ...

  8. HDU 4352 区间的有多少个数字满足数字的每一位上的数组成的最长递增子序列为K(数位DP+LIS)

    题目:区间的有多少个数字满足数字的每一位上的数组成的最长递增子序列为K 思路:用dp[i][state][j]表示到第i位状态为state,最长上升序列的长度为k的方案数.那么只要模拟nlogn写法的 ...

  9. ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K. Poor Ramzi -dp+记忆化搜索

    ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K. ...

随机推荐

  1. DFS练习一---HDU 1342

    参考文章来源:http://blog.csdn.net/pengwill97/article/details/54850852 题目在这里:HDU.1342 最近在练习DFS,就找了一些题来做,力求自 ...

  2. ELK+kafka日志处理

    此次使用kafka代替redis,elk集群搭建过程请参考:https://www.cnblogs.com/dmjx/p/9120474.html kafka名词解释: 1.话题(Topic):是特定 ...

  3. ajax状态值和状态码

    AJAX状态值是指,运行AJAX所经历过的几种状态,无论访问是否成功都将响应的步骤,可以理解成为AJAX运行步骤.如:正在发送,正在响应等,由AJAX对象与服务器交互时所得:使用“ajax.ready ...

  4. python简介,数据类型,input,if语句

      1. python的起源 python的创始人为吉多·范罗苏姆(龟叔Guido van Rossum),1989年的圣诞节期间,龟叔为了在阿姆斯特丹打发时间 决心开发一个新的脚本程序解释器,作为A ...

  5. laravels -- Swoole加速php

    LaravelS是一个胶水项目,用于快速集成Swoole到Laravel,然后赋予它们更好的性能.更多可能性. 环境 : ubuntu16 + nginx + php7.1 + LaravelS搭建高 ...

  6. Python中的str

    str_lst = [ ('元素替换',), ('字符串切片',), ('字符串分割',), ('字符串连接',), ('元素计数',), ('寻找元素',), ('判断字符串的开头与结尾',), ( ...

  7. C++基础 namespace register bool

    1. namespace (1)命令空间 C中的命名空间 在C中只有一个全局作用域 C语言中所有全局标识符共享同一个作用域 标识符之间可能发生冲突 C++中提出了命名空间的概念 命令空间将全局作用域分 ...

  8. Reward HDU - 2647

    传送门     Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to dis ...

  9. [Bzoj3252]攻略(dfs序+线段树)

    Description 题目链接 Solution 可以想到,每次肯定是拿最大价值为最优 考虑改变树上一个点的值,只会影响它的子树,也就是dfs序上的一个区间, 于是可以以dfs序建线段树,这样就变成 ...

  10. 全方位认识HDMI接口技术

    HDMI接口并不是一个开放的标准.制造商必须向HDMI标准制定协会支付版税,来换取一个生产许可证.不过这个版税可不便宜,每年要交纳15000美元的许可费,并且更黑的是每生产一个HDMI接口就要支付0. ...