CF285 E Positions in Permutations——“恰好->大于”的容斥和允许“随意放”的dp

题目:http://codeforces.com/contest/285/problem/E

是2018.7.31的一场考试的题,当时没做出来。

题解:http://www.cnblogs.com/yanshannan/p/9410986.html

因为那个值对于 i 位置来说只和 i 位置放了 i-1 或 i+1 有关,所以状态里记录一下 i 和 i+1 有没有已经放过,再加上 i-1 的对于 i-1 和 i 的状态,就能转移了。

枚举这一位:放 i-1 /放 i+1/先空下。先空下对那个值无影响,所以可以做到;最后相当于指定了 j 个位置放什么值,剩下的位置乘上一个排列即可。

随便往空下的位置放可能导致多一些值,所以最后容斥一下即可。

注意初值赋给那个状态!

那场考试的其余信息就见 Zinn 的博客吧。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1005,mod=1e9+7;
int n,m,dp[N][N][2][2],jc[N],jcn[N],ans,f[N];
int pw(int x,int k)
{int ret=1;while(k){if(k&1ll)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1ll;}return ret;}
void init()
{
  jc[0]=1; for(int i=1;i<=n;i++) jc[i]=(ll)jc[i-1]*i%mod;
  jcn[n]=pw(jc[n],mod-2);
  for(int i=n-1;i>=0;i--) jcn[i]=(ll)jcn[i+1]*(i+1)%mod;
}
void upd(int &x){x-=(x>=mod?mod:0);}
int C(int n,int m){return (ll)jc[n]*jcn[m]%mod*jcn[n-m]%mod;}
int main()
{
  scanf("%d%d",&n,&m);
  init();
  dp[0][0][1][0]=1;//so pos1 can‘t 0!!!!!!
  for(int i=1;i<=n;i++)
    for(int j=0;j<=n;j++)//n
    for(int k=0;k<=1;k++)
      {
        dp[i][j][k][0]=dp[i-1][j][0][k]+dp[i-1][j][1][k],
          upd(dp[i][j][k][0]);//rand
        if(j)dp[i][j][k][1]=dp[i-1][j-1][0][k]+dp[i-1][j-1][1][k],
           upd(dp[i][j][k][1]),//i+1
           dp[i][j][k][0]+=dp[i-1][j-1][0][k],
           upd(dp[i][j][k][0]);//i-1
      }
  for(int i=m;i<=n;i++)
    f[i]=(ll)(dp[n][i][0][0]+dp[n][i][1][0])*jc[n-i]%mod;
  ans=f[m];
  for(int i=m+1,fx=-1;i<=n;i++,fx=-fx)
    ans+=(ll)f[i]*C(i,i-m)%mod*fx,ans+=(fx==1?0:mod),upd(ans);
  printf("%d\n",ans);
  return 0;
}

原文地址:https://www.cnblogs.com/Narh/p/9651971.html

时间: 2024-08-29 13:12:30

CF285 E Positions in Permutations——“恰好->大于”的容斥和允许“随意放”的dp的相关文章

codeforces 340E Iahub and Permutations(错排or容斥)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Iahub and Permutations Iahub is so happy about inventing bubble sort graphs that he's staying all day long at the office and writing permutations. Iahubina is angry that she is no more import

Codeforces 285 E. Positions in Permutations

\(>Codeforces \space 285 E. Positions in Permutations<\) 题目大意 : 定义一个长度为 \(n\) 的排列中第 \(i\) 个元素是好的,当且仅当 \(i\)在排列中的位置 \(p_i\) 满足 \(|i - p_i| = 1\), 给出 \(n, k\) 求长度为 \(n\) 的排列中恰好有 \(k\) 个元素是好的方案数 $1 \leq n \leq 1000, 0 \leq k \leq n $ 解题思路 : 观察发现,直接求出答案

CF285E Positions in Permutations(dp+容斥)

题意,给定n,k,求有多少排列是的 | p[i]-i |=1 的数量为k. Solution 直接dp会有很大的后效性. 所以我们考虑固定k个数字使得它们是合法的,所以我们设dp[i][j][0/1][0/1]表示前i个数,填了j个数,当前位置有没有被选,下一位有没有被选,这样做的话,转移会比较简单. 那么除去这j个数,剩下的数随便填,乘上全排列就好了. 但这样会多算. 然后这种问题有一个容斥模型,直接套上就好了. #include<iostream> #include<cstdio&g

【CF285E】Positions in Permutations

题目 刷水题涨信心 显然这是个广义容斥,我们现在算一下至少有\(i\)个完美数的方案数就好了 这\(1000\)的数据范围显然在暗示\(n^2\)的dp 我们注意到这个条件大概就是\(P_i=i-1\)或\(P_i=i+1\),于是我们可以想象成左右两边各\(n\)个点去完成一个一一匹配 设\(dp[i][j][k][p]\)表示左边第\(i\)个数已经匹配完了,一共形成了\(j\)对完美数,\(k\)表示右边对应的第\(i\)个位置的使用状态\(0/1\),\(p\)表示右边第\(i+1\)个

双元素非递增(容斥)--Number Of Permutations Educational Codeforces Round 71 (Rated for Div. 2)

题意:https://codeforc.es/contest/1207/problem/D n个元素,每个元素有a.b两个属性,问你n个元素的a序列和b序列有多少种排序方法使他们不同时非递减(不同时good). 思路: 真难则反+容斥,反向考虑,ans1=如果a序列非递减则有a中各个数字出现次数的阶乘的乘积个,ans2=b序列也是一样. ans3=然后还要减去a序列和b序列都是good的方案数,就是元素相同的出现次数阶乘的乘积(注意,如果不存在双good就不算ans3). ANS就是:全排列 -

CH5E26 扑克牌

题意 5E26 扑克牌 0x5E「动态规划」练习 描述 一副不含王的扑克牌由52张牌组成,由红桃.黑桃.梅花.方块4组牌组成,每组13张不同的面值.现在给定52 张牌中的若干张,请计算将它们排成一列,相邻的牌面值不同的方案数. 牌的表示方法为XY,其中X为面值,为2.3.4.5.6.7.8.9.T.J.Q.K.A中的一个.Y为花色,为S. H.D.C中的一个.如2S.2H.TD等. 输入格式 第一行为一个整数T,为数据组数. 之后每组数据占一行.这一行首先包含一个整数N,表示给定的牌的张数,接下

涂色游戏 题解

bsoj6412 没找到出处... 题意简述:给一颗树,一次操作定义为随机选择一个点,染掉该点和它周围一圈的点,问期望多少次染黑所有点. 这是道好题啊!全面考察了容斥.反演.期望和dp,有许多值得注意的细节. 一.做法1(容斥/二项式反演+dp) 1.1 化式子 首先肯定第一个想到的式子就是 \[ Ans = \sum_{i=1}^{\infty} i * P(在染第i次时刚好黑完) \] 这是根据期望的定义直接得到的. 然后发现这个\(i\)实在是非常的恶心,因为它居然和无穷有关.但既然是一个

【题解】CF#175(Div. 2) E-Positions in Permutations

挺有收获的一道题ヾ(?°∇°?)?? 恰好为 m ,这个限制仿佛不是很好处理.一般而言,我所了解的恰好为 k 的条件,不是用组合数 / dp状态转移 / 斜率二分就只剩下容斥了.我们可以先处理出 num[i] 表示至少有 i 个完美位置的方案数,之后再容斥得到 ans[m] (恰好为 m 个).如何获得 num 数组?建立dp状态为 f[i][j][p][q], (其中p, q为01状态)表示dp到第 i 个位置,已经出现了 j 个完美的位置,且 i 和 i + 1 是否被用过.转移的时候分情况

组合数取模(转载)

本文转自:http://blog.csdn.net/skywalkert/article/details/52553048 0. 写在前面 在程序设计中,可能会碰到多种类型的计数问题,其中不少涉及到组合数的计算,所以笔者写下这么一篇文章,期望能解决一些常规的组合数求模问题.以下部分内容改编自AekdyCoin的<组合数求模>,而且为了感谢他对(懵懂的)笔者的启发,这篇文章的标题与其文章相同.另外,感谢Picks将多项式运算的技巧在中国进行推广,感谢51nod提供了许多有趣的数论题目,感谢fot