首页 > 其他分享 >CF980-Div2-D

CF980-Div2-D

时间:2024-10-30 21:41:57浏览次数:6  
标签:le int cin mx 操作 CF980 Div2 dis

CF980-Div2-D

题意

从 \(1\) 开始决策,若选当前数,则累计贡献 \(a[i]\) 并跳到 \(j\) 位置,\(j\) 是 \(\lt i\) 且没有决策过(包括选了和没选)的最大位置(操作 \(1\))。若不选当前数,则跳转到 \(j\) 位置,\(j\) 是 \(\le b[i]\) 且没有决策过(包括选了和没选)的最大位置(操作 \(2\))。求最大得分。

思路

看到的第一眼以为是动态规划,想了一下觉得dp顺序太难搞了,好像也会有后效性。(但据说dp能做?)

考场上猜了一个结论:应该可以找一个拐点,到达之后就一直用操作 \(1\)。下来一看这个结论是对的。

感性理解一下,就是用操作 \(2\) 一定是为了能拿更远处的数,当操作 \(2\) 不再优后,我们只用操作 \(1\) 就是最优的。

设我们用操作 \(2\) 放弃了 \(p_1,p_2,\dots,p_m\),最后拐点是 \(i\)。(也是最远点,因为不是最远点的话肯定不优)

所以答案就是 \(\max_{1 \le i \le n} presum[i] - \sum_{1 \le j \le m}a[p_j]\)。

现在问题转化成了对于每个 \(i\),我们要最小化 \(\sum_{1 \le j \le m}a[p_j]\),即 “放弃贡献”。

这些点并不是按编号大小依次放弃的,也存在顺序问题,考虑构图。

我们连边 \((i \to i - 1, 0), (i \to b[i], a[i])\)。最后得到一张带权有向图。

用 \(dijkstra\) 跑一遍,\(dis[i]\) 就是最小的 “放弃贡献”。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
#define int ll
using namespace std;
using ll = long long;
const int N = 4e5 + 5;
const int inf = 0x3f3f3f3f3f3f3f3f;
struct node{
	int v, w, ne;
}e[N << 1];
int T, n, idx = 0;
int a[N], b[N], dis[N], sm[N], first[N];
bool vis[N];
void add(int x, int y, int z){
	e[++ idx] = (node){y, z, first[x]};
	first[x] = idx;
}
priority_queue<pair<int, int> > q;
int solve(){
	cin >> n;
	F(i, 1, n) first[i] = vis[i] = 0, dis[i] = inf;
	dis[1] = idx = 0;

	F(i, 1, n) cin >> a[i], sm[i] = sm[i - 1] + a[i];
	F(i, 1, n) cin >> b[i], add(i, b[i], a[i]);
	F(i, 2, n) add(i, i - 1, 0);
		
	q.push({0, 1});
	while(q.size()){
		int u = q.top().second;
		q.pop();
		if(vis[u]) continue;
		vis[u] = 1;
		for(int i = first[u]; i; i = e[i].ne){
			int v = e[i].v, w = e[i].w;
			if(dis[v] > dis[u] + w){
				dis[v] = dis[u] + w;
				q.push({-dis[v], v});
			}
		}
	}
	
	int mx = 0;
	F(i, 1, n) mx = max(mx, sm[i] - dis[i]);
	return mx;
}
signed main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> T;
	while(T --){
		cout << solve() << '\n';
	}
	return fflush(0), 0;
}

总结

首先是要大胆猜结论,好验证的话就拿小样例验证一下,更重要的是利用这个性质做进一步的处理。

对于转移顺序没有明显规律,视具体数据的题,考虑构图

遇到最大化问题,尝试转成最小化问题,或许就会有更多发挥空间,比如用 dijkstra 跑最短路,二分之类的。

参考博客

Codeforces Round #980 Editorial - Codeforces

Codeforces Round 980 div2 个人题解(A~D) - ExtractStars - 博客园

标签:le,int,cin,mx,操作,CF980,Div2,dis
From: https://www.cnblogs.com/superl61/p/18516678

相关文章

  • Codeforces Round 982 div2 个人题解(A~D2)
    CodeforcesRound982div2个人题解(A~D2)Dashboard-CodeforcesRound982(Div.2)-Codeforces火车头#define_CRT_SECURE_NO_WARNINGS1#include<algorithm>#include<array>#include<bitset>#include<cmath>#include<cstdio>#in......
  • CF round 979 div2(D-E)
    D容易观察到需要连续一段区间。这不单点修改区间查询,然后我思维就开始往线段树飘了。。。并且我到这里就以为做完了开始想实现,实际上性质都没观察准确。。但是因为这是一个1500的题所以显然有不用线段树的解。题解是差分做的,确实差分也可以操作区间观察到“LR”一定是隔断点,那......
  • Codeforces Round 979 div2 个人题解(A~E)
    CodeforcesRound979div2个人题解(A~E)Dashboard-CodeforcesRound979(Div.2)-Codeforces火车头#define_CRT_SECURE_NO_WARNINGS1#include<algorithm>#include<array>#include<bitset>#include<cmath>#include<cstdio>#inc......
  • VP CF975 div2
    前言别人说这场好,我就打打A简单模拟,分奇偶位置即可。B一开始没注意到端点的边界问题,后来分讨了一下,把端点和中间的点分开考虑即可C卡了1h的唐题,首先由于每堆中不能出现同种卡牌,所以答案一定<=n。当时想到这就开二分答案了,发现k=0的情况过不了,以为是特殊边界问题,直接特......
  • Codeforces Rund 977 div2 个人题解(A~E1)
    CodeforcesRund977div2个人题解(A,B,C1,C2,E1)Dashboard-CodeforcesRound977(Div.2,basedonCOMPFEST16-FinalRound)-Codeforces火车头#define_CRT_SECURE_NO_WARNINGS1#include<algorithm>#include<array>#include<bitset>#includ......
  • Codeforces 972 div2
    A-SimplePalindrome1、先对字母进行分配,每个字母分到n/5个2、对剩余字母进行分配,前n%5个字母每一个分配一个3、分别将其输出,相同字母放在一起,如果相同字母分开,就会出现如“ABA”这样的回文子串。AC代码:#include<bits/stdc++.h>usingnamespacestd;charss[7]={......
  • CF div2 round 960
    C.MadMADSum手玩规律题,预处理两次就能得到一个规律的答案。#include<bits/stdc++.h>usingnamespacestd;#definels(x)(x<<1)#definers(x)((x<<1)+1)intread(){ intret=0;charc=getchar(); while(c<'0'||c>'9')c=getc......
  • Codeforces 169 Div2
    AClosestPoint由题意可得三个及以上的点无法插入新的点,只有两个点时可以插入但当两个点间隔为1时同样无法插入先判断,后输出就行#include<bits/stdc++.h>usingnamespacestd;constintN=50;intt,n;inta[N];intmain(){ cin>>t; while(t--){ cin>>n; for(i......
  • 965div2补题
    A.FindKDistinctPointswithFixedCenter思路简单构造,我居然在这个题上因为没看懂英文还有机翻英太过逆天导致我WA了好几发......ACcode:#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;voidsolve(){intx,y,k;cin>>x>>y>>k;in......
  • CF1998 div2 & abc366
    1CF1.1B被诈骗了。我们的构造要向“每个区间只有1个数不一样考虑”。1.2C比较难。但是出的好。注意到如果我们不删除中位数这个位置的数,那么那个数是一定的。所以我们可以把\(k\)加到最大的可以加的数上,统计答案就在这个数,然后二分算中位数即可。其它策略?我们可不......