• Codeforces Round #688(Div 2) 题解


    A.显然碰撞当且仅当编号相同,答案是编号相同的数量.
    B.考虑差分数组可以发现答案是相邻差绝对值之和.枚举每个位置考虑把它修改成与它相邻的数后的答案.
    C.考虑与坐标轴平行的边是同一行.
    1.枚举每行最左边和最右边的(d),第(3)个点新增的点在第(1)行或第(n)行.
    2.枚举每行的每个(d),第(2)的点是最上边或最下边的(d),第(3)个新增的点在这行最左边或最右边.
    列的情况同理.
    D.使用搜索引擎知道连续过(n)关的期望为(2^{n+1}-2).当(k)为奇数时无解,当(k)为偶数时每次贪心取最大的(n)构造即可.
    upd:记连续过(n)关的的期望为(E_n),考虑递推式,(E_{n+1}=E_n+1+dfrac12E_{n+1}),即连续过完(n)关后,有一半概率再过一关即可,有一半概率需要从头再来.
    考虑到(E_0=0),可以解出通项是(E_n=2^{n+1}-2).设计关卡时由于每两个检查点之间是独立的,期望就是各段期望之和.
    E.可以发现序列是DFS序.(f[u])表示结点(u)到它子树中最近叶子距离.动态规划可以算出(f).
    考虑每个非根非叶子结点,可以发现对其每个儿子(v)都要满足(kge f_v+2).
    对于根节点,可以发现对其除至多一个儿子之外的每个儿子(v)都要满足(kge f_v+2).
    最后还需要(kge f_1).
    F.如果唯一路径是(u_1=1,u_2,cdots,u_m=n),那么要满足(u_{i+1}le u_i+a_{u_i}<u_{i+2}),并且对于所有(u_i<j<u_{i+1},j+a_j<u_{i+1}).
    (dp[i][j][k])表示从(n)开始考虑到第(i)位,唯一路径后两个位置位(j)(k)的最小代价.
    两种转移.
    1.(i)不在当前路径中,(dp[i][j][k]leftarrow dp[i+1][j][k]+[jle i+a_i]),因为(jle i+a_i)的时候,需要把第(i)位修改成(0),代价(+1).
    2.(i)在当前路径中,(dp[i][i][j]leftarrow dp[i+1][j][k]),需要满足(jle i+a_i<k).
    考虑维护二维矩阵(dp[][j][k]),对所有(i+1le jle i+a_i),第二种操作本质是(dp[][i][j]=min_{k>i+a_i}dp[][j][k]),第一种操作是(dp[][j][k])+=(1).
    upd:想要维护这两个操作,需要对每行求后缀最小值,以及进行整行(+1)的操作,下面代码中的dp数组实际上是dp数组的后缀最小值,add[j]是对第一种对第(j)(+1)操作进行标记.
    代码可以这样写:

    int n;
    cin >> n;
    vector<int> a(n + 1);
    for(int i = 1; i <= n; i += 1) cin >> a[i];
    vector<int> add(n + 1);
    vector<vector<int>> dp(n + 1, vector<int>(n + 2, n));
    dp[n][n + 1] = 0;
    for(int i = n - 1; i >= 1; i -= 1)
        for(int j = i + a[i]; j >= i + 1; j -= 1)
            dp[i][j] = min(dp[i][j + 1], dp[j][i + a[i] + 1] + add[j] ++);
    cout << dp[1][2] << "
    ";
    
  • 相关阅读:
    英雄联盟离线更新方法
    (七) Keras 绘制网络结构和cpu,gpu切换
    剑指offer | 链表中的倒数第K个结点 | 12
    剑指offer | 从尾到头打印链表 | 11
    剑指offer | 栈的压入,弹出序列 | 10
    剑指offer | 包含min函数的栈 | 09
    剑指offer | 调整数组顺序使奇数位于偶数前面 | 08
    剑指offer | 旋转数组的最小数字 | 07
    剑指offer | 两个栈实现一个队列 | 06
    剑指offer | 替换空格 | 05
  • 原文地址:https://www.cnblogs.com/Heltion/p/14088245.html
Copyright © 2020-2023  润新知