首页 > 其他分享 >cfRound933div3-E题解

cfRound933div3-E题解

时间:2024-03-17 22:12:19浏览次数:25  
标签:cfRound933div3 前缀 int 题解 花费 vector 队列 dp

E-Rudolf and k Bridges

题意:

选择的桥在连续的行中,每个桥的支架安装位置是可以不一样的.

做法:赛时也感觉也感觉是dp,但是害怕dp,就选择了逃避.往贪心方向想,认为每次到了每个跳板都要跳到最远距离,实际上这样是不行的.很明显,可能存在近一点的点花费更少。

实际上是dp,而且也不难。首先容易想到,需要一个前缀和,记录每个一行最少的花费的前缀和.然后枚举选择的连续的区间就好了。问题是每一行的最少花费怎么算。这其实是一个简单dp问题,对于一个普遍的点,他可能从他的前d+1个点来的,很明显,在前d+1个点中选花费最小那个就好了.如果每次都遍历前d+1个点, 找到到达那个点的最小值的话,这样复杂度很高。这个时候关键来了!用一个优先队列(小根堆)存放所有经历过的点的花费和下标,如果堆顶的点离现在的点超过d+1,直接pop.那么此时只要存在堆里的,都是合法范围的,而且堆顶必然是花费最小的,即从堆顶那个点跳到当前这个点即是最优的.然后把dp[i][m]加到前缀和,之后枚举区间,更新ans即可.

void solve(){               //E  跳板--是不对,到了某个点之后,不一定要跳尽,才是最好的;;
    // 求每一行最小的代价(dp)+前缀和
    //优先队列优化dp!!不用优先队列的话,因为每次需要前面合法的格子的最小代价是多少,需要遍历,这个时候就适合用优先队列,不用遍历去找最小代价.
    int n,m,k,d;   //n行,m列,建连续k桥,最大支架间隔d
    cin>>n>>m>>k>>d;
    vector<vector<int>> arr(n+1,vector<int>(m+1));
    vector<vector<int>> dp(n+1,vector<int>(m+1,0));
    int pre[105]={0};
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>arr[i][j];
        }
    }
    for(int i=1;i<=n;i++){
        priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pq;   //小根堆
        dp[i][1]=1,pq.emplace(1,1);
        for(int j=2;j<=m;j++){
            while(pq.size()&&pq.top().second+d+1<j) pq.pop();
            dp[i][j]=arr[i][j]+1+pq.top().first;
            pq.emplace(dp[i][j],j);
        }
    }
    for(int i=1;i<=n;i++) pre[i]=pre[i-1]+dp[i][m];
    //int ans=INT_MAX;            //INT_MAX不够大!!!!如果没有看错误样例,这里又要找错找很久很久都找不出来。。。经典错误!!
    int ans=LONG_LONG_MAX;
    for(int i=k;i<=n;i++) ans=min(ans,pre[i]-pre[i-k]);
    cout<<ans<<endl;
}

ps!!ans要初始化为LONG_LONG_MAX,因为INT_MAX不够大.经典细节.

 

标签:cfRound933div3,前缀,int,题解,花费,vector,队列,dp
From: https://www.cnblogs.com/ouhq/p/18079293

相关文章

  • [ABC258F] Main Street 题解
    题意:你要在平面直角坐标系中行走,每一步可以上下左右四个方向任意移动$1$,耗时$k$秒。特别地,存在若干条快速通道,若该步起点和终点均满足$x\equiv0\pmod{B}$或$y\equiv0\pmod{B}$,则认为该步是在快速通道上进行,仅需耗时$1$秒。询问从$(S_x,S_y)$到$(G_x,G_y)$最......
  • P3939 数颜色 题解
    题目链接:数颜色经典题目了,暴力数据结构随便过,不过这种不带修的单个颜色的数量查找有个经典的做法:分桶+二分。具体的为每个颜色分桶,记录有序下标,这样就可以二分出\([l,r]\)上的下标个数。对于一次交换来说,如果相邻的颜色相同那么并不会发生交换,如果不同那么就发生交换,由于下标在......
  • P10218 [省选联考 2024] 魔法手杖 题解
    Description给定\(a_1,a_2,\dots,a_n\)以及\(b_1,b_2,\dots,b_n\),满足\(a_i\in[0,2^k-1]\)以及\(b_i\geq0\),你需要给出\(S\subseteq\{1,2,\dots,n\}\)以及\(x\in[0,2^k-1]\)满足以下条件:\(\sum\limits_{i\inS}b_i\leqm\);满足以上条件的前提下,最大化\......
  • P2746 [USACO5.3] 校园网Network of Schools 题解
    题目链接:校园网NetworkofSchools这个题得翻译下题目意思才知道在干嘛,题目一开始表明了这个是一个有向图,因为边是单向的。其次关于第一个问题:基于一个事实,如果有\(x\rightarrowy\rightarrowz\),那么只需要\(x\)接受协议,它所在的\(scc\)强连通分量上的点一定都能不需要......
  • AT_abc345_c [ABC345C] One Time Swap 题解
    题目传送门解法对于\(S_{i}\),设\(num_{S_{i}}\)表示\(S_{i+1\simn}\)中\(S_{i}\)出现的次数,则\(S_{i}\)对答案产生的贡献为\(n-i-num_{S_{i}}\)。注意原串在存在两个相同的元素的时候,也要统计在内。代码#include<bits/stdc++.h>usingnamespacestd;#definell......
  • P2163 [SHOI2007] 园丁的烦恼 题解
    题目链接:园丁的烦恼挺经典的题目,转化成二维数点去做这玩意和常规的偏序计数问题有区别:转化为求\(a\lex\leb\\&\&\c\ley\led\)的数量,这种就别想着拆来拆去了,这种权值类带偏序计数类问题,是经典的可差性问题,我们计:\(ans(x,l,r)\)表示\(t\lex,l\ley\ler\)的数......
  • P3302 [SDOI2013] 森林 题解
    题目链接:森林有意思的树上可持久化线段树变形题,建议先看这个:P2633Countonatree题解对于本题而言,我们重新阐述树上可持久化线段树的核心思想,对于点路径/边路径上的第\(k\)大问题,我们使用树上前缀和问题的思想,将其转化为可差性问题:一条路径上的权值线段树可以拆分为几棵权......
  • 贪心算法题解
    前言大家好,我是jiantaoyab,这篇文章将给大家介绍贪心算法和贪心算法题目的练习和解析,贪心算法的本质就是每一个阶段都是局部最优,从而实现全局最优。我们在做题的同时,不仅要把题目做出来,还要有严格的证明。柠檬水找零在柠檬水摊上,每一杯柠檬水的售价为5美元。顾客排队......
  • codeforce Round 934 div2 个人题解(A~C)
    A.DestroyingBridges时间限制:1秒内存限制:256兆输入:标准输入输出:标准输出有$n$个岛屿,编号为$1,2,…,n$。最初,每对岛屿都由一座桥连接。因此,一共有$\frac{n(n-1)}{2}$座桥。Everule住在岛屿$1$上,喜欢利用桥梁访问其他岛屿。Dominater有能力摧毁最多$k$座......
  • AtCoder-abc345_f题解
    题意简述给定一个无向图。你要在其中选出一些边,使得选出的边所构成的图中,度数为奇数的点有\(K\)个。如果可以,输出选了哪些边,否则输出-1。思路首先在选一条边时,边两端点度数的奇偶性一定都会改变,即要么都变为奇数,要么两个点的奇偶性交换过来,要么都变为偶数。这三种情况时满足......