CS Academy Distinct Neighbours(经典dp)

题意:

求相邻无相同数字的合法的排列数

题解:

题解

先将相同的数字分为一类,假设共有n组

定义\(dp[i][j]\)表示前i组数字恰好有j对相邻数字相同的方案数,那么最后答案就是dp[n][0]

已经考虑完了前\(i\)组数,现在考虑第\(i+\)组数,如何放置

首先可以枚举放\(k\)个位置,有\(C(cnt[i+1]-1,k-1)\)种放法,然后将这k个位置分成两类

一类放在相同的数字中间 放了\(L\)个位置,有\(C(j,L)\)种那么相邻相同的对数变成\(j - L\)对

一类不放相同的数字中间 放\(k - L\) 个位置,有\(C(S - j,k - L)\)种

最后第\(i+1\)组数 增加了\(cnt[i+1] - k\)对相邻相同的数,即最后变成\(dp[i+1][j - L + cnt[i+1] - k]\)

四层循环 复杂度\(O(n^{3})\)

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 800;
const int mod = 1e9 + 7;
int C[N][N];
void init(){
for(int i = 0;i < N;i++) C[i][0] = C[i][i] = 1;
for(int i = 2;i < N;i++){
for(int j = 1;j <= i;j++){
C[i][j] = (C[i-1][j] + C[i-1][j-1])%mod;
}
}
}
int dp[N][N],cnt[N],total[N];
vector<int> v;
int main(){ init();
int n,x,mx = 1;
cin>>n;
v.push_back(0);
for(int i = 1;i <= n;i++){
cin>>x;
if(!cnt[x]) v.push_back(x);
cnt[x]++;
}
for(int i = 1;i < v.size();i++) total[i] = total[i-1] + cnt[v[i]];
dp[0][0] = 1;
for(int i = 0;i < v.size() - 1;i++){
int num = cnt[v[i+1]],S = total[i]+1;
for(int j = S-1;j >= 0;j--){///j对不同
int kk = min(num,S);///kk个位置可选择
for(int k = 1;k <= kk;k++){
int L = min(j,k);
for(int l = L;S - j >= k - l;l--){
int &res = dp[i+1][j - l + num - k];
res = (res + 1LL * C[num - 1][k - 1] * C[j][l] % mod * C[S-j][k-l]%mod * dp[i][j]%mod)%mod;
}
}
}
}
cout<<dp[v.size()-1][0]<<endl;
return 0;
}

听说还有\(O(n^{2})\)的做法 用到了下面这个东西,研究一下再写写

有\(n_1\)个\(a_1\),\(n_2\)个\(a_2\),...\(n_r\)个\(a_r\)的相邻无相同的排列方法数

\[f(n_1,n_2,...,n_r) = \sum_{1<=t_i<=n_i}^{r}\coprod_{i=1}^{r}(-1)^{n_i-t_i}\binom{n_i-1}{t_i-1}\frac{(t_1+t_2+...+t_r)!}{t_1!t_2!...t_r!}
\]

CS Academy Distinct Neighbours(经典dp)的更多相关文章

  1. CS academy Binary Flips(dp)

    开学啦,没啥时间写博客..过几天就能又停课啦qwq 做点中等 \(dp\) 题来找找 noip 的感觉 233 题意 原题戳这里. 给你一个 \(n \times m\) 的矩阵 \(A\) ,一开始 ...

  2. HDU 1003 Max Sum --- 经典DP

    HDU 1003    相关链接   HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...

  3. poj1458 求最长公共子序列 经典DP

    Common Subsequence Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 45763   Accepted: 18 ...

  4. NYOJ - 矩形嵌套(经典dp)

    矩形嵌套时间限制:3000 ms | 内存限制:65535 KB 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b< ...

  5. 51nod 1412 AVL树的种类(经典dp)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1412 题意: 思路: 经典dp!!!可惜我想不到!! $dp[i][k] ...

  6. NYOJ 16 矩形嵌套(经典DP)

    http://acm.nyist.net/JudgeOnline/problem.php?pid=16 矩形嵌套 时间限制:3000 ms  |           内存限制:65535 KB 难度: ...

  7. poj 1050 To the Max 最大子矩阵和 经典dp

    To the Max   Description Given a two-dimensional array of positive and negative integers, a sub-rect ...

  8. 【经典dp 技巧】8.13序列

    经典的拆绝对值 题目大意 给定$n$个具有顺序的序列,允许对每个序列循环移动.记第$i$个序列尾元素为$x$,$i+1$个序列首元素为$y$,定义其连接收益为$|x-y|*i$,求$n$个序列连接最大 ...

  9. POJ 1160:Post Office 邮局经典DP

    Post Office Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17168   Accepted: 9270 Desc ...

随机推荐

  1. 用struct LNode *L与LinkList &L的区别

    用void InitList(struct LNode *L), 函数InitList中如果改变了L指针本身的值,对其他函数无影响.用void InitList(LinkList &L),函数 ...

  2. ORM初级实战简单的数据库交互

    setting.py中: """ Django settings for untitled3 project. Generated by 'django-admin st ...

  3. javascript遍历方法总结

    forEach 循环 JavaScript诞生已经有20多年了,我们一直使用的用来循环一个数组的方法是这样的: for (var index = 0; index < myArray.lengt ...

  4. python协程和IO多路复用

     协程介绍                                                                                                ...

  5. java程序——输入判断成绩

    import java.util.*; class ExceptionOut extends Exception{ } public class Score { public static void ...

  6. python datetime offset-aware与offset-navie相互转换

    python datetime offset-aware与offset-navie相互转换 2016年11月13日 16:20:43 阅读数:2393 有时,我们使用python 的datetime模 ...

  7. Result Maps collection does not contain value for xxxx

    这是mybatis查询返回值的错误,我在做一个查询数值的方法,但是我是这样写的: <select id="findSize" resultMap="long&quo ...

  8. 网易考拉Android客户端网络模块设计

    本文来自网易云社区 作者:王鲁才 客户端开发中不可避免的需要接触到访问网络的需求,如何把访问网络模块设计的更具有扩展性是每一个移动开发者不得不面对的事情.现在有很多主流的网络请求处理框架,如Squar ...

  9. druid sqlparser使用例子

    package com.alibaba.druid.bvt.sql.mysql; import java.util.List; import org.junit.Assert; import com. ...

  10. VS的几个实用快捷键

    Ctrl + K, D格式化代码 Ctrl + L 删除一行 Ctrl + K, S调出自动代码块 svm之后二下TAB 生成Main方法 Ctrl + K,C注释代码块Ctrl+K,U取消注释