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驱动中使用LED子系统

    在Linux驱动中使用LED子系统 原文:https://blog.csdn.net/hanp_linux/article/details/79037684 前提配置device driver下面的L ...

  2. Android系统启动:2-Init篇

    Android系统启动:Init篇 原文:http://gityuan.com/2016/02/05/android-init/ 概述 init进程是Linux系统中用户空间的第一个进程,进程号固定为 ...

  3. 安卓Camera-HAL显示值与比例

    安卓Camera-HAL显示值与比例 参考:https://blog.csdn.net/wang714818/article/details/78049649?utm_source=blogxgwz4 ...

  4. arm linux 移植 iperf3

    背景 新做的硬件需要有进行一些板级接口测试:关于网络的测试很多时候只是停留在 ping 通:能够使用就算了.不知道网络的丢包率,也不知道网络吞吐的性能. 因此,需要使用一些专业化的工具来进行测试:查阅 ...

  5. C#语言编写的仅有8KB大小的简易贪吃蛇开源游戏

    前言 今天大姚给大家分享一款由C#语言编写的仅有8KB大小的简易贪吃蛇开源游戏:SeeSharpSnake. 项目特点 该仓库中的项目文件和脚本可以用多种不同的配置构建相同的游戏,每个配置生成的输出大 ...

  6. 基于RK3588的8K视频解码显示案例分享!引领超高清工业视频时代

    8K.4K.2K显示对比 2K分辨率:也称为全高清(FULL HD),它具有1920 x 1080像素的分辨率.这是目前大多数消费者电视和电脑显示器的标准分辨率,可以提供良好的图像质量. 4K分辨率: ...

  7. vscode 使用 python 进行 UG 二次开发 实现代码提示功能

    vscode 使用 python 进行 UG 二次开发的 实现代码提示功能 用 VSCODE 进行 UG 二次开发的时候, 想要用代码提示的时候,可以用 pydev 插件, 但是,pydev 只有一个 ...

  8. Lambda表达式常见用法

    Lambda介绍 Lambda,别名函数式编程 函数式编程是一种编程范式.它把计算当成是数学函数的求值,从而避免改变状态和使用可变数据.它是一种声明式的编程范式,通过表达式和声明而不是语句来编程. L ...

  9. Known框架实战演练——进销存数据结构

    系统主要包含商品信息.商业伙伴(客户.供应商)信息.业务单表头信息.业务单表体信息.对账单表头信息.对账单表体信息. 1. 商品信息(JxGoods) 该表用于存储公司商品信息. 名称 代码 类型 长 ...

  10. 后端说,单页面SPA和前端路由是怎么回事

    没有请求的路由 在传统开发中,浏览器点击一个超链接,就会像后端web服务器发送一个html文档请求,然后页面刷新.但开始单页面开发后,就完全不同了. 单页面?这个概念难以理解.我用一个js作为整个we ...