• ARC104部分题目简要题解


    虽然早上太困了,vp打得很垃圾

    但是自己手玩出E,F还有有点激动的

    D.

    分数规划后多重背包即可

    不是很难,但是要记住多重背包复杂度是可以优化的qwq

    看到分数的话,一般要么就斜率优化,要么就分数规划

    E.

    可以先枚举数的相对大小关系(包括有多少个数互不相同)

    然后可以根据差分数组将值域分成若干个区间,根据这个关系继续爆搜,注意到若干个上下界相同的区间中选一个单调递增的子序列的方案数就是一个组合数

    因为范围很小,自己想了一个爆搜套爆搜的做法,跑的飞快,思维难度为0,但是巨难写(写了2h+)

    比较好的做法可以参考这篇 blog ( orz xgzc , orz Itst) ARC104 E

    F.

    很有意思的题

    题意简述:定义对于一个大小为 (n) 的数组 H, (P_i) 为 最大的 (j),满足((H_j > H_i)),如果不存在,令 (P_i = -1),现在要求你计算对于所有满足 (H_i leq X_i)的 H 数组,本质不同的 P 有多少个

    (n leq 100,X_i leq 1e5)

    solution

    我们不妨推一下 (P_i) 等于某个值 (x) ,需满足什么

    可以发现,若 (P_i = j),则 (H_j ge H_i + 1)

    (P_i = -1),那么 (H_i) 必然 (ge max_{j = 1}^{i - 1}H_j)

    可以发现根据 (P_i) ,我们可以连一颗以((H_i,i))为二维关键字排序的笛卡尔树

    那么每个 (P) 数组都会对应一颗笛卡尔树

    那么问题转化成了有多少个合法的本质不同笛卡尔树(即定义两个笛卡尔树相同,当且仅当父子关系都相同,不考虑键值)

    我们考虑假设一个笛卡尔树的根当前允许的最大键值为 (H),

    • 对于左儿子 (lc) ,它的最大键值则为 (min(H,X[lc]))

    • 对于右儿子(rc), 它的最大键值则为(min(H - 1,X[rc]))

    若任意一个点,允许的最大键值(leq 0),则不合法,否则合法

    于是可以用一个区间 (dp) 来解决这个问题,令dp[l][r][h][0/1]表示当前解决 ([l,r]) 这个区间,根在最左边或者最右边,根的权值为(h)的方案数

    最后答案即为 (sum_{rt = 1}^n dp(l,rt,X[rt],1) * dp(rt,n,X[rt],0))

    复杂度(O(n^4))

    #include <bits/stdc++.h>
    using namespace std;
    int read() {
    	char c = getchar();
    	int x = 0;
    	while(c < '0' || c > '9')	c = getchar();
    	while(c >= '0' && c <= '9')	x = x * 10 + c - 48,c = getchar();
    	return x;
    }
    const int _ = 1e2 + 7;
    int dp[_][_][_][2];/*0 at left,1 at right*/
    bool vis[_][_][_][2];
    int X[_];int n;
    const int mod = 1e9 + 7;
    void add(int &x,int y) {
    	x += y - mod;
    	x += (x >> 31) & mod; 
    }
    int calc(int l,int r,int h,int o) {
    	if(vis[l][r][h][o])	return dp[l][r][h][o];
    	if(h <= 0)	return 0;
    	if(l == r)	return 1;/*为空*/
    	vis[l][r][h][o] = 1;
    	int dl = l,dr = r;
    	if(o == 1)	dr--;
    	else	dl++;
    	int H = h - (o == 0);/*如果是右儿子的话,最大可允许值-1*/
    	for(int rt = dl; rt <= dr; ++rt){
    //		cout<<rt<<' '<<calc(dl,rt,min(X[rt],h),1)<<' '<<calc(rt,dr,min(X[rt],h - 1),0)<<'
    ';
    		add(dp[l][r][h][o],1ll * calc(dl,rt,min(X[rt],H),1) * calc(rt,dr,min(X[rt],H),0) % mod);
    	}
    	return dp[l][r][h][o];
    }
    int main() {
    	n = read(); 
    	for (int i = 1; i <= n; ++i)	X[i] = min(read(),n);
    	int ans = 0;
    	for (int rt = 1; rt <= n; ++rt) {
    		add(ans,1ll * calc(1,rt,X[rt],1) * calc(rt,n,X[rt],0) % mod);
    	}
    	cout << ans << '
    ';
    	return 0;
    }
    
  • 相关阅读:
    AcWing 838. 堆排序
    AcWing 240. 食物链
    Sublime下载地址
    【转载】Java 8 Optional的正确姿势
    【SpringBoot】通过server.servlet.context-path设置应用的上下文路径
    【java/Lamda】List.stream().collect(Collectors.toMap(Emp::getId, a->a,(k1,k2)->k2))的意义
    Prometheus修改数据保留时间
    Atitit BLE 协议栈 艾提拉总结 目录 1. ——关于BLE的一些基本概念——
    Atitit 高并发设计实践 艾提拉著 目录 1. 并发的实现俩中模式 并发角度来看 基于事件触发vs线程的 1 2. 负载均衡 1 2.1. 云服务模型paas caas faas+http
    Atitit 锁的不同层级 app锁 vm锁 os锁 硬件锁 目录 1. 在硬件层面,CPU提供了原子操作、关中断、锁内存总线的机制 1 1.1. test and set指令 1 1.2. 锁内
  • 原文地址:https://www.cnblogs.com/y-dove/p/14842855.html
Copyright © 2020-2023  润新知