codeforces 840 C. On the Bench(多重集合的交错排列经典题目)
来源:互联网 发布:画板软件在线 编辑:程序博客网 时间:2024/05/22 08:13
题目链接
C. On the Bench
分析
这是一道多重集合交错排列的经典题目,经典的题意是这样的:
设集合
A 有n1个a1,n2个a2,...,ni个ai 问使其相邻两个数不相同的排列有多少种.
我们先来解决这个经典题目,然后再来解决codeforces的这个题目.
可以用 dp+容斥做
先来解决一个简化的问题
设
设
上面那个不就是个背包吗?递推就好了
知道了
dp[k]∗k! 表示的是有n−k 个数相邻
所以有
将原题的完全平方数处理掉就是经典问题了
AC code
#include<bits/stdc++.h>#define pb push_back#define mp make_pair#define PI acos(-1)#define fi first#define se second#define INF 0x3f3f3f3f#define INF64 0x3f3f3f3f3f3f3f3f#define random(a,b) ((a)+rand()%((b)-(a)+1))#define ms(x,v) memset((x),(v),sizeof(x))#define scint(x) scanf("%d",&x );#define scf(x) scanf("%lf",&x );#define eps 1e-10#define dcmp(x) (fabs(x) < eps? 0:((x) <0?-1:1))#define lc o<<1#define rc o<<1|1using namespace std;typedef long long LL;typedef long double DB;typedef pair<int,int> Pair;const int maxn = 300+10;const int MAX_V= 500+10;const int MOD = 1e9+7;LL a[maxn];LL C[maxn][maxn];LL A[maxn];LL dp[maxn][maxn];std::map<LL, int> ma;LL power_mod(LL x,LL n){ LL ret =1; while (n) { if(n&1)ret = ret * x %MOD; x = x*x %MOD; n >>=1; } return ret;}void init(){ C[0][0] = 1; for(int i=1 ; i<maxn ; ++i){ C[i][0] =1; for(int j=1 ; j<maxn ; ++j){ C[i][j] =(C[i-1][j] + C[i-1][j-1]) % MOD; } } A[0]=1; for (int i=1 ; i<maxn ; ++i) A[i] = A[i-1]*i % MOD;}int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n; init(); cin>>n; for(int i=0 ; i<n ; ++i){ LL x;cin>>x; for(int j=2 ; j*j <= x ; ++j){ while (x % (j*j) ==0) { x/=(j*j); } } ma[x] ++; } ms(dp,0);dp[0][0] =1; int cnt =1; for(auto e : ma){ for(int i=1 ; i<=n ; ++i){ //dp[cnt-1][0] =1; int m = min(e.se,i); for(int j = 1 ; j<=m ; ++j){ LL tmp = A[e.se]; tmp = tmp * C[e.se-1][j-1] % MOD; tmp = tmp *power_mod(A[j],MOD-2) % MOD; dp[cnt][i] += dp[cnt-1][i-j]*tmp; dp[cnt][i] %= MOD; } } cnt ++; } //for(int i=0 ; i<=n ; ++i)std::cout << dp[cnt-1][i] << '\n'; LL ans =dp[cnt-1][n] *A[n]% MOD;int k=0; for(int i =n-1 ; i>=0 ; --i){ if(k&1)ans = (ans+dp[cnt-1][i]*A[i] )% MOD; else{ ans = (ans - dp[cnt -1][i] * A[i] + MOD) % MOD; } k ^=1; } std::cout << ans << '\n'; //std::cout << "time "<< clock()/1000 <<"ms"<< '\n'; return 0;}
阅读全文
0 0
- codeforces 840 C. On the Bench(多重集合的交错排列经典题目)
- [DP] Codeforces 840C .On the Bench
- Codeforces 840C On the Bench 【容斥+DP】
- codeforces 840C On the Bench 容斥+DP
- Codeforces-840C On the Bench(dp)
- codeforces840C On the Bench -- DP
- 多重集合的排列和组合问题
- 多重集合的排列与组合
- 多重集合的排列和组合问题
- 多重集合的排列和组合问题
- CF840C On the Bench(dp+组合数学)
- 有关多重集合的排列和组合问题
- 多重集的全排列
- Codeforces Round #286 (Div. 2) C. Mr. Kitayuta, the Treasure Hunter(经典的DP)
- (noip 模拟 Fseq)<转化为多重集合的排列问题>
- hdu 6143 容斥原理+多重集合的排列数 2017 Multi-University Training Contest
- Codeforces 106C 多重背包
- 经典的C语言面试题目
- 会场安排问题 区间重叠问题
- yum错误:except KeyboardInterrupt, e:
- jQuery学习笔记7
- java虚拟机(二,虚拟机中对象创建过程)
- CSS秘密花园: Sticky footers
- codeforces 840 C. On the Bench(多重集合的交错排列经典题目)
- PHP GD库
- 一款非常适合新手练习的开源项目
- 【视频开发】Gstreamer框架中使用gst-launch进行流媒体播放
- 简单工厂
- UE4 C++控制在UMG控件中播放视频
- jQuery学习笔记8
- FTP
- c++类的内存布局