zoukankan      html  css  js  c++  java
  • JZOJ 3481. 【NOIP2013模拟10.23】君と彼女の恋(DP+组合数)

    JZOJ 3481. 【NOIP2013模拟10.23】君と彼女の恋

    题目大意

    • 给定 N , M N,M N,M,求不同的序列数使得序列所有数之和为 M M M,且两两在除以 M M M后余数互不相同。
    • N ≤ 1 0 18 Nle 10^{18} N1018 M ≤ 100 Mle 100 M100.

    题解

    • 暴力可以考虑把 m o d    M mod M modM的取值状压,设 f i , j f_{i,j} fi,j表示选的数和为 i i i m o d    M mod M modM是否出现过的状态为 j j j的方案数,转移显然,最后答案要乘个数的阶乘。
    • 但这样复杂度不能接受,由于 N N N特别大,但 M M M较小,DP时可以只算 [ 0 , m ) [0,m) [0,m)中的数,再把剩余部分用组合数计算上,
    • 这样一来,不需要记录状态,因为这个范围内它们除以 M M M的余数本身就互不相同,只需设 f i , j f_{i,j} fi,j表示和为 i i i,选了 j j j个数的方案数,转移也显然。
    • 至于最后怎么计算,首先需要满足 M ∣ N − i M|N-i MNi才能是一种合法的答案,还需要把 N − i M frac{N-i}{M} MNi M M M分配给 j j j个数,用挡板法求得方案数为 ( N − i M + j − 1 j − 1 ) frac{N-i}{M}+j-1choose {j - 1} (j1MNi+j1),当然也还要乘上 j ! j! j!

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define md 905229641
    #define ll long long
    #define M 110
    ll f[2][M][M * M], inv[M];
    ll C(ll x, ll y) {
    	ll s = 1;
    	for(ll i = x; i > x - y; i--) s = s * (i % md) % md;
    	for(int i = 1; i <= y; i++) s = s * inv[i] % md;
    	return s;
    }
    int main() {
    	ll n; int m , i, j, k;
    	scanf("%lld%d", &n, &m);
    	inv[1] = 1;
    	for(i = 2; i <= m; i++) inv[i] = inv[md % i] * (md - md / i) % md;
    	f[1][0][0] = 1;
    	for(i = 0; i < m ;i++) {
    		int o = i % 2;
    		memset(f[o], 0, sizeof(f[o]));
    		for(j = 0; j <= m; j++)		
    			for(k = 0; k <= m * j; k++) {
    				f[o][j][k] = f[1 - o][j][k];
    				if(k >= i) (f[o][j][k] += f[1 - o][j - 1][k - i]) %= md;
    			}
    	}
    	int o = 1 - m % 2; ll t = 1, ans = 0;
    	for(j = 1; j <= m; j++) {
    		t = t * j % md;
    		for(k = 0; k <= m * j; k++) if(f[o][j][k] && (n - k) % m == 0) {
    			ans = (ans + t * f[o][j][k] % md * C((n - k) / m + j - 1, j - 1)) % md;
    		}
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    无限风光 : 近来地形算法学习小结
    上帝的天空之岛
    Layered>Variance>Shadow Map
    好事多磨:Ogre1.7 编译记
    蒙特卡罗(Monte Carlo)方法(转自百度百科)
    linux下压缩打包命令合辑
    Ubuntu Linux 环境搭建|adnroid篇
    个人知识管理(转)
    ubuntu 跳强技巧(转)
    Ubuntu Linux环境搭建|Java篇
  • 原文地址:https://www.cnblogs.com/LZA119/p/14279498.html
Copyright © 2011-2022 走看看