zoukankan      html  css  js  c++  java
  • 洛谷P4104 [HEOI2014]平衡(dp 组合数学)

    题意

    题目链接

    Sol

    可以把题目转化为从([1, 2n + 1])中选(k)个数,使其和为((n+1)k)

    再转化一下:把((n+1)k)划分为(k)个数,满足每个数在范围在([1, 2n + 1])

    这时候就可以用整数划分的思路dp了(然鹅我还是想不出来。。)

    因为每个数互不相同,因此我们可以把每个阶段划分出来的数都看做不降的

    (f[i][j])表示前(i)个数,和为(j)且满足条件的方案数。

    我们考虑最小的数是否是(1)

    若不是(1),则映射到所有数(-1),也就是(f[i][j - i])

    若是(1),这时候相当于对于(f[i - 1][j - (i-1)])的所有数(+1),同时在最前面补上(1),方案为(f[i - 1][j - i])

    然后再减去最大的数超过(2n+1)的方案,也就是(f[i][j - (2n + 2)])

    复杂度(O(Tnk^2))

    #include<bits/stdc++.h>
    #define Fin(x) freopen(#x".in", "r", stdin);
    using namespace std;
    const int MAXN = 50001;
    int mod;
    template<typename A, typename B> inline bool chmax(A &x, B y) {return x < y ? x = y, 1 : 0;}
    template<typename A, typename B> inline bool chmin(A &x, B y) {return x > y ? x = y, 1 : 0;}
    template<typename A, typename B> inline A mul(A x, B y) {return 1ll * x * y % mod;}
    template<typename A, typename B> inline void add2(A &x, B y) {x = x + y >= mod ? x + y - mod : x + y;}
    template<typename A, typename B> inline int add(A &x, B y) {return x + y >= mod ? x + y - mod : x + y;}
    inline int read() {
    	char c = getchar(); int x = 0, f = 1;
    	while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    	return x * f;
    }
    int fp(int a, int p) {
        int base = 1;
        while(p) {
            if(p & 1) base = mul(base, a);
            a = mul(a, a);  p >>= 1;
        }
        return base;
    }
    int inv(int x) {
    	return fp(x, mod - 2);
    }
    int f[101][100001];
    void solve() {
    	int N = read(), K = read(); mod = read();
    	memset(f, 0, sizeof(f));
    	f[0][0] = 1;
    	for(int j = 1; j <= (N + 1) * K; j++)
    		for(int i = 1; i <= min(j, K); i++) {
    			f[i][j] = add(f[i][j - i], f[i - 1][j - i]);
    			if(j >= 2 * N + 2) add2(f[i][j], -f[i - 1][j - (2 * N + 2)] + mod);
    		}
    	cout << f[K][(N + 1) * K] << '
    ';
    }
    signed main() {
    	for(int T = read(); T--; solve());
    	return 0;
    }
    
  • 相关阅读:
    nyoj 202 红黑树
    nyoj 237 游戏高手的烦恼
    nyoj 203 三国志
    nyoj 118 修路方案
    nyoj 714 Card Trick
    nyoj 710 外星人的供给站
    nyoj 712探 寻 宝 藏
    nyoj 709 异 形 卵
    nyoj 711 最舒适的路线
    HTML5表格简单应用案例之[招聘需求表]
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/10440040.html
Copyright © 2011-2022 走看看