• BZOJ3193: [JLOI2013]地形生成


    传送门

    Sol

    第一问可以考虑按照山的高度从大到小放
    但是这样如果遇到高度相同的就不好考虑,那么同时要求数量限制从小到大
    这样每次放的时候后面的一定不会影响前面,并且高度相同的时候前面能放的位置后面的也能放
    直接乘起来就好了
    对于第二问,此时高度相同的会有影响
    对于高度相同的一段,强制要求数量限制从小到大,并且后面的位置必须小于前面
    (f_{i,j}) 表示放了 (i) 个到 (j) 个空位,最后一个放的在最后,的方案数
    那么 (f_{i,j}=sum_{kle j}f_{i-1,k})
    前缀和优化即可,最后把答案乘起来

    # include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn(1005);
    const int mod(2011);
    
    struct Hill {
    	int h, c;
    
    	inline bool operator < (Hill b) const {
    		return (h ^ b.h) ? h > b.h : c < b.c;
    	}
    } h[maxn];
    
    int n, f[maxn][maxn];
    
    inline int Solve(int l, int r) {
    	register int i, j, len = r - l + 1;
    	for (i = 0; i <= len; ++i)
    		for (j = 0; j <= l; ++j) f[i][j] = 0;
    	for (i = 1; i <= l; ++i) f[0][i] = 1;
    	for (i = 1; i <= len; ++i) {
    		for (j = 1; j <= min(l, h[i + l - 1].c); ++j) f[i][j] = f[i - 1][j];
    		for (j = 1; j <= l; ++j) f[i][j] = (f[i][j] + f[i][j - 1]) % mod;
    	}
    	return f[len][l];
    }
    
    int main() {
    	register int i, c, ans;
    	scanf("%d", &n);
    	for (i = 1; i <= n; ++i) scanf("%d%d", &h[i].h, &h[i].c);
    	sort(h + 1, h + n + 1);
    	for (ans = 1, i = 2, c = 0; i <= n; ++i) {
    		c = h[i].h == h[i - 1].h ? c + 1 : 0;
    		ans = ans * min(i, h[i].c + c) % mod;
    	}
    	printf("%d ", ans);
    	for (ans = 1, i = 1, c = 0; i <= n; ++i)
    		if (i == n || h[i].h != h[i + 1].h) ans = ans * Solve(i - c, i) % mod, c = 0;
    		else ++c;
    	printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    Android笔记
    Scala中apply的用法
    MySQL备忘
    Spring test
    Scala
    Dubbo
    Scala元组
    Scala中None, Nil, Nothing的区别
    java多态与异常处理——动手动脑
    《大道至简》第七八章读后感
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/10165301.html
Copyright © 2020-2023  润新知