zoukankan      html  css  js  c++  java
  • JZOJ 5192. 【NOI2017模拟7.2】容器 (dp)

    https://gmoj.net/senior/#contest/show/2376/1

    题解:

    考虑把区间拆成左端点和右端点,(T)的限制相当于任何一个时候,没有匹配的左端点(le T)

    (f[i][p][q])表示刚刚确定了(i)的右括号,和(i+1)的左括号,匹配了(p)个区间,还有(q)左括号。

    转移可以枚举下一步选多少,顺便分配是那些跳蚤选了这些左括号和右括号就行了。

    一直纠结于用(frac{k!}{prod a[i]!})去计算分配方案,事实上不用,这样也做不了。

    Code:

    #include<bits/stdc++.h>
    #define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
    #define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
    #define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
    #define ll long long
    #define pp printf
    #define hh pp("
    ")
    using namespace std;
    
    const int mo = 1011110011;
    
    const int N = 45;
    
    int n, k, t;
    ll c[N][N];
    
    ll f[N][N][N];
    
    void add(ll &x, ll y) {
    	(x += y) %= mo;
    }
    
    int main() {
    	freopen("container.in", "r", stdin);
    	freopen("container.out", "w", stdout);
    	scanf("%d %d %d", &n, &k, &t);
    	fo(i, 0, 40) {
    		c[i][0] = 1;
    		fo(j, 1, i) c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mo;
    	}
    	f[0][0][0] = 1;
    	n ++;
    	fo(i, 1, n) {
    		fo(p, 0, k) fo(q, 0, k) if(f[i - 1][p][q]) {
    			fo(u, 0, q)	fo(v, 0, k - p - q) {
    				int np = p + u, nq = q - u + v;
    				if(np + nq > k || nq > t) continue;
    				add(f[i][np][nq], f[i - 1][p][q] * c[q][u] % mo * c[k - p - q][v]);
    			}
    		}
    	}
    	ll ans = f[n][k][0];
    	pp("%lld
    ", ans);
    }
    
    
  • 相关阅读:
    Set和Map
    将博客搬至CSDN
    (转)VS制作安装包
    C#俄罗斯方块实现思路及源码
    ASP.NET网站部署过程
    2016百度之星资格赛总结
    数据库编程常见错误总结
    (转)Android 如何全局获取Context
    Android数据文件存储
    关于工程文档中图表的使用
  • 原文地址:https://www.cnblogs.com/coldchair/p/12913433.html
Copyright © 2011-2022 走看看