NEC Programming Contest 2022 (AtCoder Beginner Contest 267) C D E

https://atcoder.jp/contests/abc267

C - Index × A(Continuous ver.)

不难想到前缀和,处理两个前缀和:

\(S1_i=\sum_{j=i}^{n}a_j\)

\(S2_i=\sum_{j=i}^{n}S1_j\)

那么题目中的式子就能转化为:

\(\sum_{i=l}^{l+m-1}i \cdot a_i=S2_i-S2_{i+m}-m\cdot S1_{i+m}\)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=2e5+5;
ll n,m;
ll a[N],s1[N],s2[N],ans;
int main(){
	scanf("%lld%lld",&n,&m);
	ans=-1e18;
	for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
	for(ll i=n;i;i--) s1[i]=s1[i+1]+a[i];
	for(ll i=n;i;i--) s2[i]=s2[i+1]+s1[i];
	for(ll i=1;i<=n-m+1;i++)
		ans=max(s2[i]-s2[i+m]-m*s1[i+m],ans);
	cout << ans;
	return 0;
}

D - Index × A(Not Continuous ver.)

直接DP

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=2e3+5;
ll n,m;
ll a[N],f[N][N];
int main(){
	scanf("%lld%lld",&n,&m);
	memset(f,-0x3f,sizeof(f));
	for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
	for(ll i=0;i<=n;i++) f[i][0]=0;
	for(ll i=1;i<=n;i++){
		for(ll j=1;j<=m;j++){
			f[i][j]=max(f[i-1][j],f[i-1][j-1]+j*a[i]);
		}
	}
	cout << f[n][m];
	return 0;
}

E - Erasing Vertices 2

贪心,每次拿最小的

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+5;
int n,m;
int a[N];
ll s[N];
ll ans;
bool t[N];
vector<int>e[N];
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > pq;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	for(int i=1;i<=n;i++) {
		for(auto j : e[i])
			s[i]+=a[j];
		pq.push(make_pair(s[i],i));
	}
	while(!pq.empty()){
		ll sum=pq.top().first;
		int u=pq.top().second;
		pq.pop();
		if(t[u]) continue;
		t[u]=1;
		ans=max(ans,sum);
		for(auto v : e[u]){
			s[v]-=a[u];
			pq.push(make_pair(s[v],v));
		}
	}
	printf("%lld",ans);
	return 0;
}
posted @ 2022-09-10 19:49  KevinLikesCoding  阅读(24)  评论(0编辑  收藏  举报