题面

传送门

思路

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

只有模$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. ARC下需要注意的内存问题

    之前发了一篇关于图片加载优化的文章,还是引起很多人关注的,不过也有好多人反馈看不太懂,这次谈谈iOS中ARC的一些使用注意事项,相信做iOS开发的不会对ARC陌生啦.这里不是谈ARC的使用,只是介绍下 ...

  2. 给大家一个我的QQ群

    很少关注博客了,提供一个QQ群讨论 我的一个QQ群:158351344

  3. Spring 中IOC(控制反转)&& 通过SET方式为属性注入值 && Spring表达式

    ### 1. Spring IoC IoC:Inversion of control:控制反转:在传统开发模式下,对象的创建过程和管理过程都是由开发者通过Java程序来实现的,操作权在开发者的Java ...

  4. Q&A - Nginx是做什么的?tomcat结合Nginx使用小结

    相信很多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那究竟它有什么作用呢?可能很多人未必了解. 说到反向代理,可能很多人都听说,但具体什么是反向代理,很多人估计就不清楚了 ...

  5. js | javascript实现浏览器窗口大小被改变时触发事件的方法

    转载 当浏览器的窗口大小被改变时触发的事件window.onresize 为事件指定代码: 代码如下: window.onresize = function(){ } 例如: 浏览器可见区域信息: 代 ...

  6. IE hack 和手机尺寸

        来自为知笔记(Wiz)

  7. JavaScript---DOM对象(DHTML)

    1.什么是DOM? DOM 是 W3C(万维网联盟)的标准.DOM 定义了访问 HTML 和 XML 文档的标准: "W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本 ...

  8. Allowed memory size of 134217728 bytes exhausted (tried to allocate 2 bytes)

    出现  Allowed memory size of 134217728 bytes exhausted (tried to allocate 2 bytes)时在php.ini文件中配置 memor ...

  9. PHP队列的实现

    队列是一种特殊的线性表,它只允许在表的前端,可以称之为front,进行删除操作:而在表的后端,可以称之为rear进行插入操作.队列和堆栈一样,是一种操作受限制的线性表,和堆栈不同之处在于:队列是遵循“ ...

  10. POJ:1222-EXTENDED LIGHTS OUT(矩阵反转)

    EXTENDED LIGHTS OUT Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12956 Accepted: 8186 ...