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. ADB命令与Dumpsys alarm查看应用程序唤醒命令

    ADB命令与Dumpsys alarm查看应用程序唤醒命令 背景 在研究设备的低功耗突然唤醒时,看到了对应的唤醒源: [ 75.813476] suspend ns: 75813465022\x09s ...

  2. 生成数字csv

    csv文件: import time import mcpi.minecraft as minecraft import mcpi.block as block mc = minecraft.Mine ...

  3. 【论文阅读】RAL2022: Make it Dense: Self-Supervised Geometric Scan Completion of Sparse 3D LiDAR Scans in Large Outdoor Environments

    0. 参考与前言 论文链接:https://ieeexplore.ieee.org/document/9812507 代码链接:https://github.com/PRBonn/make_it_de ...

  4. QT自定义右键菜单

    利用QMenu和QAction可以实现非常实用的右键菜单功能.具体实现思路如下: 1.在xxx.h文件中添加如下头文件 #include <QMenu> #include <QCon ...

  5. Redis 高阶应用

    生成全局唯一 ID 全局唯一 ID 需要满足以下要求: 唯一性:在分布式环境中,要全局唯一 高可用:在高并发情况下保证可用性 高性能:在高并发情况下生成 ID 的速度必须要快,不能花费太长时间 递增性 ...

  6. 一个难忘的json反序列化问题

    前言 最近我在做知识星球中的商品秒杀系统,昨天遇到了一个诡异的json反序列化问题,感觉挺有意思的,现在拿出来跟大家一起分享一下,希望对你会有所帮助. 案发现场 我最近在做知识星球中的商品秒杀系统,写 ...

  7. documen.write 和 innerHTML 的区别?

    document.write只能重绘整个页面,innerHTML可以重绘页面的一部分. 1. ducument.write使用举例html文档: <!doctype html> <h ...

  8. 今天我们来聊Java IO模型,BIO、NIO、AIO三种常见IO模型

    一.写在开头 很久没更新喽,最近build哥一直在忙着工作,忙着写小说,都忘记学习自己的本职了,哈哈,不过现在正式回归! 我们继续学习Java的IO相关内容,之前我们了解到,所谓的IO(Input/O ...

  9. 解决方案 | 一个VBA代码里面非常隐蔽的错误:运行时错误“5”:无效的过程调用或参数

    1 代码部分 代码功能:实现使用sumatra打开指定pdf指定页码 代码: Sub OpenPDFatPage() Dim PDFFile As String Dim PageNumber As L ...

  10. 深入解读RabbitMQ工作原理

    RabbitMQ简介 在介绍RabbitMQ之前首先要介绍一下MQ,MQ是什么?MQ全称是Message Queue,可以理解为消息队列的意思. RabbitMQ是一个实现了AMQP(Advanced ...