codeforces-285E \(Positions \ in \ Permutations\)

$$codeforces$$

题意

给定一个序列长度为 \(n\) 的序列 , \(A=\{1 \dots n\}\)

对于 \(A\) 的排列 \(P\) , 位置 \(i\) 的值为 \(p_i\) , 定义这个点为好的满足以下条件:

\[|p_i - i| = 1
\]

即 \(p_i = i + 1 \ or \ i - 1\)

问对于 \(A\) 的排列中恰好有 \(K\) 个好点的排列数。

\(k \le n \le 1000\) .

题解

定义 \(dp_{i , j , l_{(2)} , k_{(2)}}\) 为长度为 \(i\) , 有 \(j\) 个点已经被挑出作为好点的 \(\bf{取法}\) ( 或者理解为至少有 \(j\) 个好点 ) , \(l\) 表示 \(i\) 是否被选 , \(k\) 表示 \(i + 1\) 是否被选.

我们可以获得如下转移方程:

dp[i][j][0][0] = ( dp[i][j][0][0] + dp[i - 1][j][0][0] + dp[i - 1][j][1][0] ) % mod ;
dp[i][j][1][0] = ( dp[i][j][1][0] + dp[i - 1][j][0][1] + dp[i - 1][j][1][1] ) % mod ; if ( j ) {
dp[i][j][0][0] = ( dp[i][j][0][0] + dp[i - 1][j - 1][0][0] ) % mod ;
dp[i][j][1][0] = ( dp[i][j][1][0] + dp[i - 1][j - 1][0][1] ) % mod ; if( i != n ) {
dp[i][j][0][1] = ( dp[i][j][0][1] + dp[i - 1][j - 1][1][0] + dp[i - 1][j - 1][0][0] ) % mod ;
dp[i][j][1][1] = ( dp[i][j][1][1] + dp[i - 1][j - 1][1][1] + dp[i - 1][j - 1][0][1] ) % mod ;
} }

解释一下:

当 \(i\) 位置不选时 , 考虑得到:

\[dp_{i , j , 0 , 0} += dp_{i - 1 , j , 1 , 0} + dp_{i - 1 , j , 0 , 0}
\]
\[dp_{i , j , 1 , 0} += dp_{i - 1 , j , 0 , 1} + dp_{i - 1 , j , 1 , 1}
\]

当 \(i\) 位置选 \(i - 1\) :

\[dp_{i , j , 1 , 0} += dp_{i - 1 , j - 1 , 0 , 0}
\]
\[dp_{i , j , 1 , 1} += dp_{i - 1 , j - 1 , 0 , 1}
\]

当 \(i\) 位置选 \(i + 1\) :

\[dp_{i , j , 0 , 1} += dp_{i - 1 , j - 1 , 0 , 0} + dp_{i - 1 , j - 1 , 1 , 0}
\]
\[dp_{i , j , 1 , 1} += dp_{i - 1 , j - 1 , 0 , 1} + dp_{i - 1 , j - 1 , 1 , 1}
\]

仔细思考易得其正确性。

设一个 \(ans_i\) 表示长度为 \(n\) , 有至少 \(i\) 个好点排列数,易得:

\[ans_i = dp_{n , i , 0 , 0} + dp_{n , i , 1 , 0} \times (n - i)!
\]

易得最后答案为:

\[answer = \sum^{n}_{i = K}(-1)^{i - K} \times C^{K}_{i} \times ans_i
\]

code

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std ;
const int N = 1e3 + 10 ;
const int mod = 1e9 + 7 ; int n , m , K ;
int dp[N][N][2][2] , ans[N] , answer ; inline int read() {
int x = 0 , f = 1 ;
char c = getchar() ; while ( c < '0' || c > '9' ) { if ( c == '-' ) f = -f ; c = getchar() ;
} while ( c >= '0' && c <= '9' ) {
x = x * 10 + c - '0' ;
c = getchar() ;
} return x * f ;
} namespace Combination {
int D[N] ; int nueyong[N] , sum_neo[N] , sum[N] ; inline void lear_neoyong() { sum_neo[0] = sum_neo[1] = 1 ;
nueyong[1] = 1 ; nueyong[0] = 1 ;
sum[0] = sum[1] = 1 ; for( int i = 2 ; i < N ; ++ i ) { int p = mod ;
int k = p / i ;
nueyong[i] = ( k * ( p - nueyong[p % i] ) ) % p ;
sum_neo[i] = ( nueyong[i] * sum_neo[i - 1] ) % p ;
sum[i] = ( i * sum[i - 1] ) % p ; }
} int Quick_Pow( int alpha , int beta ) {
int ans = 1 ; while ( beta > 0 ) { if( beta & 1 ) ans = ( ans * alpha ) % mod ; beta >>= 1 ; alpha = ( alpha * alpha ) % mod ;
} return ans ;
} int Regular_C_of_Pow_Class( int n , int m ) {
int alpha = 1 , beta = 1 , rereturn = 0 ; if( m <= n && n >= 0 && m >= 0 ) { for( int i = n - m + 1 ; i <= n ; ++ i ) {
alpha = ( alpha * i ) % mod ; }
for( int i = 1 ; i <= m ; ++ i ) {
beta = ( beta * i ) % mod ;
} rereturn = ( alpha * Quick_Pow( beta , mod - 2 ) ) % mod ;
return rereturn ; } else return 0 ; } inline int jc( int x ) {
return sum[x] ;
} inline int neo_jc( int x ) { if ( x == 0 ) return 1 ; return sum_neo[x] ;
} int Regular_C_of_Inv( int n , int m ) {
return ( ( ( jc( n ) * neo_jc( n - m ) ) % mod ) * neo_jc( m ) ) % mod ;
} int C_Lucas_Using_Inv( int n , int m ) { if ( m > n ) return 0 ; if ( m == 0 ) return 1 ; return ( Regular_C_of_Inv( n % mod , m % mod ) * C_Lucas_Using_Inv( n / mod , m / mod ) ) % mod ;
} int C_Lucas_Using_Pow( int n , int m ) { if( m == 0 ) return 1 ; return ( Regular_C_of_Pow_Class( n % mod , m % mod ) * C_Lucas_Using_Pow( n / mod , m / mod ) ) % mod ;
} void Asking_for_Derangement() { D[0] = 1 ;
D[1] = 0 ;
D[2] = 1 ;
for( int i = 3 ; i < N ; ++ i ) { D[i] = ( i - 1 ) * ( D[i - 1] + D[i - 2] ) % mod ; }
} int Regular_A( int n , int m ) {
return ( jc( n ) * neo_jc( n - m ) ) % mod ;
} inline void Cleared() {
memset( D , 0 , sizeof(D) ) ;
memset( sum_neo , 0 , sizeof(sum_neo) ) ;
memset( sum , 0 , sizeof(sum) ) ;
memset( nueyong , 0 , sizeof(nueyong) ) ;
}
} ;
using namespace Combination ; signed main() { #ifndef ONLINE_JUDGE
freopen( "1.in" , "r" , stdin ) ;
freopen( "1.out", "w" ,stdout ) ;
#endif n = read() , K = read() ; lear_neoyong() ;
dp[1][0][0][0] = 1 ; dp[1][1][0][1] = 1 ; for ( int i = 2 ; i <= n ; ++ i ) {
for ( int j = 0 ; j <= n ; ++ j ) {
dp[i][j][0][0] = ( dp[i][j][0][0] + dp[i - 1][j][0][0] + dp[i - 1][j][1][0] ) % mod ;
dp[i][j][1][0] = ( dp[i][j][1][0] + dp[i - 1][j][0][1] + dp[i - 1][j][1][1] ) % mod ; if ( j ) {
dp[i][j][0][0] = ( dp[i][j][0][0] + dp[i - 1][j - 1][0][0] ) % mod ;
dp[i][j][1][0] = ( dp[i][j][1][0] + dp[i - 1][j - 1][0][1] ) % mod ; if( i != n ) {
dp[i][j][0][1] = ( dp[i][j][0][1] + dp[i - 1][j - 1][1][0] + dp[i - 1][j - 1][0][0] ) % mod ;
dp[i][j][1][1] = ( dp[i][j][1][1] + dp[i - 1][j - 1][1][1] + dp[i - 1][j - 1][0][1] ) % mod ;
} } }
} for ( int i = 0 ; i <= n ; ++ i ) {
ans[i] = ( jc( n - i ) * ( dp[n][i][0][0] + dp[n][i][1][0] ) ) % mod ;
// cout << i << ' ' << ans[i] << '\n' ;
} int f = - 1 ;
for ( int i = K ; i <= n ; ++ i ) {
f = -f ;
answer = ( answer + ( ( ( f * ( ans[i] * C_Lucas_Using_Inv( i , K ) ) % mod ) % mod + mod ) % mod ) % mod ) % mod ;
} cout << answer << '\n' ;
}

结尾撒花 \(\color{pink}{✿✿ヽ(°▽°)ノ✿}\)

动态规划专题--容斥原理--codeforces-285E Positions in Permutations的更多相关文章

  1. CodeForces - 285E: Positions in Permutations(DP+组合数+容斥)

    Permutation p is an ordered set of integers p1,  p2,  ...,  pn, consisting of n distinct positive in ...

  2. Codeforces 285E - Positions in Permutations(二项式反演+dp)

    Codeforces 题目传送门 & 洛谷题目传送门 upd on 2021.10.20:修了个 typo( 这是一道 *2600 的 D2E,然鹅为啥我没想到呢?wtcl/dk 首先第一步我 ...

  3. Codeforces 285 E. Positions in Permutations

    \(>Codeforces \space 285 E. Positions in Permutations<\) 题目大意 : 定义一个长度为 \(n\) 的排列中第 \(i\) 个元素是 ...

  4. 【CF285E】Positions in Permutations(动态规划,容斥)

    [CF285E]Positions in Permutations(动态规划,容斥) 题面 CF 洛谷 题解 首先发现恰好很不好算,所以转成至少,这样子只需要确定完一部分数之后剩下随意补. 然后套一个 ...

  5. 【BZOJ5302】[HAOI2018]奇怪的背包(动态规划,容斥原理)

    [BZOJ5302][HAOI2018]奇怪的背包(动态规划,容斥原理) 题面 BZOJ 洛谷 题解 为啥泥萌做法和我都不一样啊 一个重量为\(V_i\)的物品,可以放出所有\(gcd(V_i,P)\ ...

  6. 【BZOJ1042】硬币购物(动态规划,容斥原理)

    [BZOJ1042]硬币购物(动态规划,容斥原理) 题面 BZOJ Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬 ...

  7. NOIP2018提高组金牌训练营——动态规划专题

    NOIP2018提高组金牌训练营——动态规划专题 https://www.51nod.com/Live/LiveDescription.html#!#liveId=19 多重背包 二进制优化转化成01 ...

  8. 正睿国庆DAY2动态规划专题

    正睿国庆DAY2动态规划专题 排列-例题 1~n 的排列个数,每个数要么比旁边两个大,要么比旁边两个小 \(f[i][j]\) 填了前i个数,未填的数有\(j\)个比第\(i\)个小,是波峰 \(g[ ...

  9. 【【henuacm2016级暑期训练】动态规划专题 I】Gargari and Permutations

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 注意这k个序列每个都是排列. 如果在每个序列中都满足y出现在x之后的话. 那么我们从x连一条有向边至y (有一个序列不满足就不连 ( ...

  10. Codeforces Round #337 Alphabet Permutations

    E. Alphabet Permutations time limit per test:  1 second memory limit per test:  512 megabytes input: ...

随机推荐

  1. Linux 错误码

    背景 Linux的错误码包含在/usr/include/asm-generic/errno-base.h和/usr/include/asm-generic/errno.h 这两个文件内. 可用于查询. ...

  2. 『vulnhub系列』Deathnote-1

    『vulnhub系列』Deathnote-1 下载地址: https://www.vulnhub.com/entry/deathnote-1,739/ 信息搜集: 使用nmap扫描存活主机,发现主机开 ...

  3. 嵌入式HLS 案例开发步骤分享——基于Zynq-7010/20工业开发板(1)

    目 录 前 言 3 1 HLS 开发流程说明 5 1.1 HLS 工程导入 5 1.2 编译与仿真 6 1.3 综合 8 1.4 IP 核封装 10 1.5 IP 核测试 14 前 言 本文主要介绍 ...

  4. 福利来了!MoneyPrinterPlus可以自动配置环境和自动运行了

    之前开源了MoneyPrinterPlus,可以实现批量混剪视频,一键生成视频和自动发布视频的功能. 但是经常会看到小伙伴在安装过程中遇到很多问题.所以这篇文章的目的就是告诉大家怎么使用MoneyPr ...

  5. The Beauty of Physics

    绪言/1 学物理的人用不着对物理方程的意义操心,只要关心物理方程的美就够了. --狄拉克 此曲只应天上有--开普勒的和谐宇宙/11 天体的运动只不过是某种永恒的复调音乐而已,要用才智而不是耳朵来倾听. ...

  6. Nginx常用操作

    Nginx Nginx的最重要的几个使用场景 静态资源服务,通过本地文件提供服务 反向代理服务,延伸出包括缓存,负载均衡等 API服务,OpenResty 相关概念 简单请求和非简单请求 请求方法是H ...

  7. Django生成数据库表时报错 __init__() missing 1 required positional argument: 'on_delete'

    原因: 在django2.0后,定义外键和一对一关系的时候需要加上on_delete选项,此参数为了避免两个表里的数据不一致问题,不然会报错 例如: owner=models.ForeignKey(U ...

  8. 可视化—gojs 超多超实用经验分享(四)

    目录 41.监听连线拖拽结束后的事件 42.监听画布的修改事件 43.监听节点被 del 删除后回调事件(用于实现调用接口做一些真实的删除操作) 44.监听节点鼠标移入移出事件,hover 后显示特定 ...

  9. CF709B 题解

    洛谷链接&CF 链接 本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读. 题目简述 给定 \(N\) 个点,在一条数轴上,位置为 \(x_1,-,x_n\),你的位置为 \(p\) ...

  10. Spring 常用的三种拦截器详解

    前言 在开发过程中,我们常常使用到拦截器来处理一些逻辑.最常用的三种拦截器分别是 AOP. Interceptor . Filter,但其实很多人并不知道什么时候用AOP,什么时候用Intercept ...