CS Academy Distinct Neighbours(经典dp)
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\)的相邻无相同的排列方法数
\]
CS Academy Distinct Neighbours(经典dp)的更多相关文章
- CS academy Binary Flips(dp)
开学啦,没啥时间写博客..过几天就能又停课啦qwq 做点中等 \(dp\) 题来找找 noip 的感觉 233 题意 原题戳这里. 给你一个 \(n \times m\) 的矩阵 \(A\) ,一开始 ...
- HDU 1003 Max Sum --- 经典DP
HDU 1003 相关链接 HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...
- poj1458 求最长公共子序列 经典DP
Common Subsequence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 45763 Accepted: 18 ...
- NYOJ - 矩形嵌套(经典dp)
矩形嵌套时间限制:3000 ms | 内存限制:65535 KB 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b< ...
- 51nod 1412 AVL树的种类(经典dp)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1412 题意: 思路: 经典dp!!!可惜我想不到!! $dp[i][k] ...
- NYOJ 16 矩形嵌套(经典DP)
http://acm.nyist.net/JudgeOnline/problem.php?pid=16 矩形嵌套 时间限制:3000 ms | 内存限制:65535 KB 难度: ...
- poj 1050 To the Max 最大子矩阵和 经典dp
To the Max Description Given a two-dimensional array of positive and negative integers, a sub-rect ...
- 【经典dp 技巧】8.13序列
经典的拆绝对值 题目大意 给定$n$个具有顺序的序列,允许对每个序列循环移动.记第$i$个序列尾元素为$x$,$i+1$个序列首元素为$y$,定义其连接收益为$|x-y|*i$,求$n$个序列连接最大 ...
- POJ 1160:Post Office 邮局经典DP
Post Office Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 17168 Accepted: 9270 Desc ...
随机推荐
- 第34-3题:LeetCode437. Path Sum III
题目 二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数. 示例: root = [10,5,-3,3,2,null,11,3,-2,null,1], sum ...
- Java中使用webSocket
Java中使用webSocket package com.yaoqi.controller.message; import javax.websocket.*; import javax.websoc ...
- JAVAOOP集合框架
集合框架三大内容:对外的接口.接口的实现和对集合运算的算法 集合有三大类接口:List.Set.Map 共同点:都是集合接口,都可以用来存储很多对象 不同:Collection接口存储一组不唯一(允许 ...
- php-5.6.26源代码 - 扩展模块的种类,扩展模块的执行埋点
模块种类(两种) 类型一:zend的模块:(类似zend_extension=test.so) 识别方法: php.ini中以zend_extension开头的配置,如zend_extension=t ...
- Linux设置下载站点
https://blog.csdn.net/jfhkd2012/article/details/50912757
- python—— 文件的打开模式和文件对象方法 & os、os.path 模块中关于文件、目录常用的函数使用方法
引用自“鱼c工作室” 文件的打开模式和文件对象方法 : https://fishc.com.cn/forum.php?mod=viewthread&tid=45279&ext ...
- 003---wsgi和wsgiref模块
WSGI: 全称:Web Server Gatway Interface ,web服务网关接口,独立的,与django无关,他们俩只是遵循一个约定,是一个协议. wsgiref模块: 实现了WSGI协 ...
- [BZOJ3714]Kuglarz(最小生成树)
Description 魔术师的桌子上有n个杯子排成一行,编号为1,2,-,n,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品.花费\(C_{i,j}\)元,魔术师就会告诉 ...
- ARabevaluator 颜色渐变控制类
参考资料: http://blog.csdn.net/qq_33456552/article/details/52092865 实现渐变效果: ArgbEvaluator argbEvaluator; ...
- HDFS写数据和读数据流程
HDFS数据存储 HDFS client上传数据到HDFS时,首先,在本地缓存数据,当数据达到一个block大小时.请求NameNode分配一个block. NameNode会把block所在的Dat ...