首页 > 其他分享 >Codeforces Round 933 Rudolf and k Bridges

Codeforces Round 933 Rudolf and k Bridges

时间:2024-03-17 21:58:43浏览次数:31  
标签:Bridges 10 int ll 933 支架 Rudolf dp op

原题链接:Problem - E - Codeforces

题目大意:给一个行为n列为m的河流二维数组,数字代表河流的深度。题目要求连续建造k座桥,桥的定义是从第一列到第m列,每隔d需要按照支架,安装支架的代价是深度+1。问安装最少需要多少代价?

思路:单调队列优化dp,dp数组只需要一维,dp[i]的含义是从1到i建桥的最小代价。因为在i安装支架,那么上一个支架可以安装的地方就是[i-d-1,i-1],那么dp[i]=min(dp[i-1],dp[i-2],dp[i-3].....dp[i-d-1]+这个点的代价+1,但是这样明显会超时。那么就可以使用单调队列来优化中间找最小值的过程。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define endl '\n' 
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
const int N=1e6+10,mod=1e9+7;
ld pi=acos(-1.0);
int main()
{
    ios::sync_with_stdio(NULL);cin.tie(0),cout.tie(0);
    ll t;cin>>t;
	while(t--)
	{
		ll n,m,k,d;cin>>n>>m>>k>>d;
		ll min1=1e18;
		vector<ll> ans(n+10);
		vector<ll> mp(m+10);
		for(int i=1;i<=n;i++)
		{
			vector<ll> dp(m+10);
			for(int j=1;j<=m;j++)
			{
				cin>>mp[j];
			}
			dp[1]=1;//第一个点需要建立一个支架,并且第一个点的深度都是0,那么代价就是1 
			deque<ll> op; 
			for(int j=1;j<=m;j++)
			{
				while(op.size()&&j-op.front()-1>d)op.pop_front();//如果单调队列里面的下标和当前点相差大于d+1就要舍弃 
				if(op.size())dp[j]=dp[op.front()]+mp[j]+1;//从上一个最小值转移过来 
				while(op.size()&&dp[j]<=dp[op.back()])op.pop_back();//如果当前的dp值比之前优,那么就可以将之前的舍弃 保证从相差不大于d+1的最小代价转移
				op.push_back(j);
//				cout<<dp[j]<<' ';
			}
//			cout<<endl;
			ans[i]=dp[m];
		}
		//求连续的k个桥的最小代价 
		for(int i=1;i<=n;i++)
		{
			ans[i]+=ans[i-1];//前缀和优化,本题数据不大暴力可以过 
		}
		for(int i=k;i<=n;i++)
		{
			min1=min(min1,ans[i]-ans[i-k]);
		}
		cout<<min1<<endl;
	}
	return 0;
}

标签:Bridges,10,int,ll,933,支架,Rudolf,dp,op
From: https://blog.csdn.net/qq_74190237/article/details/136790629

相关文章

  • B. Rudolf and 121
    题解由于a1的值只能通过对a2的操作进行消除,所以我们可以先根据a1的值迭代出a2,a3的值,然后此时的a2,只能通过a3的操作进行消除.....以此类推,如果其中发现有ai的值<0就输出NO。code #include<bits/stdc++.h>usingnamespacestd;constintN=2e5+5;inta[N];intmain(){//......
  • C. Rudolf and the Ugly String
    题解遇到map时,sum++;遇到pie时,sum++。特殊情况遇到mapie时,sum--(因为map,pie分别加了一次,但是该子串只需要去掉p即可)code #include<bits/stdc++.h>usingnamespacestd;constintN=2e5+5;inta[N];intmain(){//freopen("input.txt","r",stdin);intt;ci......
  • A. Rudolf and the Ticket
    题解简单的二分应用,对于每个bi我们只需找到最大的ci使得bi+ci<=target即可code #include<bits/stdc++.h>usingnamespacestd;inta[105],b[105];intmain(){//freopen("input.txt","r",stdin);intt;cin>>t;while(t--){int......
  • G. Rudolf and Subway
    原题链接题解太巧妙了!!原题等效于该分层图,然后广搜本题中我用了另一种方法建边,因为清空太麻烦了code#include<bits/stdc++.h>usingnamespacestd;intmain(){ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);intt;cin>>t;while(t--)......
  • F. Rudolf and Imbalance
    原题链接题解最大值最小\(\to\)二分可行性判断:二分间断值\(len\\to\)如果原序列\(a_i-a_{i-1}>len\)\(\to\)双指针判断有没有\(b+f\)使得\(a_i-len<=b+f<=a_{i-1}+len\)由于只能使用一次,所以若使用两次也算错code#include<bits/stdc++.h>usingnamespacestd;......
  • 3.14 CF Round 933 (Div. 3)
    (1)CF1941BRudolfand121给定一个长度为\(n\)的序列\(a\)。求最少进行多少次操作后所有\(a_i=0\):选择一个\(2\lei<n\),并让\(a_i\getsa_i-2,a_{i-1}\getsa_{i-1}-1,a_{i+1}\getsa_{i+1}-1\)。我们记选择\(i=x\)时的操作为\(\opera......
  • Codeforces Round 933 (Div. 3)赛后总结
    CodeforcesRound933(Div.3)B从边缘开始计算,因为边缘肯定只能一个一个减,就可以遍历得到答案.代码C只要对mapie特判,然后判断map和pie的个数就是答案了。D(记忆化搜索)可以通过二维数组来标记搜索状态,将已经出现过的状态直接返回,极大减少时间。#include<bits/stdc++.h>......
  • Codeforces Round 933 (Div. 3) A - G 题解
    CodeforcesRound933(Div.3)A-RudolfandtheTicketSolution因为\(n\)很小,直接枚举\(b_i+c_j\)所产生的所有数字Code#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn,m,k;cin>>n>>m>>k;intans=0;......
  • CF-933(已更新:B-D)
    CF-933当天晚上舍友在玩剧本杀,不得不说那剧情实在是太狗血了,想不通他们是怎么能玩得那么起劲的但也不能当作这次发挥不好的借口/_\A题最开始没看到数据范围(D也是),B一开始就想到了思路,但调了二十多分钟,甚至因为数组开小了白白多了一次RE……D题才是最难绷的,把题看懂后自己就用......
  • Codeforces Round 933 (Div. 3)
    CodeforcesRound933(Div.3)AA-RudolfandtheTicket暴力查看代码voidsolve(){intn,m,k;cin>>n>>m>>k;vector<int>b(n),c(m);for(inti=0;i<n;++i)cin>>b[i];for(inti=0;i<m;++i)cin>>c[i];......