专栏文章
题解:P14567 【MX-S12-T2】区间
P14567题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min31x6d
- 此快照首次捕获于
- 2025/12/01 19:45 3 个月前
- 此快照最后确认于
- 2025/12/01 19:45 3 个月前
题解:P14567 【MX-S12-T2】区间
闲话:
本蒟蒻初二,冲刺 一等奖。
赛时 分钟切了第一题, 分钟切了第二题,然后就啥而不会了,喜提 分。
赛时 分钟切了第一题, 分钟切了第二题,然后就啥而不会了,喜提 分。
题意:
求一个代价最小的合法区间 。
合法区间的定义:任何一个出现在区间内的颜色都不能出现在区间外。
合法区间的定义:任何一个出现在区间内的颜色都不能出现在区间外。
思路:
提供一个简单而又略带卡常的做法。
首先先打暴力,复杂度为 。
考虑在暴力的基础上进行优化:
我们发现随着区间右端点逐渐递增,代价也逐渐递增,所以可以直接剪枝,即对于每一个左端点找到合法的下标最小的右端点并统计答案。
随着右端点的递增,如果发现存在颜色 和下标 满足 且 、,那么无论右端点怎么向右移,一定不可能再合法了,直接剪枝。
献上我的优良代码:
首先先打暴力,复杂度为 。
考虑在暴力的基础上进行优化:
我们发现随着区间右端点逐渐递增,代价也逐渐递增,所以可以直接剪枝,即对于每一个左端点找到合法的下标最小的右端点并统计答案。
随着右端点的递增,如果发现存在颜色 和下标 满足 且 、,那么无论右端点怎么向右移,一定不可能再合法了,直接剪枝。
代码:
CPP#include<bits/stdc++.h>
using namespace std;
#define I return
#define love 0
#define coding
int n,c[1000050],v[1000050],f[1000050],pre[1000050],lst[1000050],mx;
long long ans = 1e18+7;
inline long long calc(int x,int y){
long long res = 0;
for(int i = x;i <= y;++i) res+=(1LL*v[i]*f[i-x+1]);
return res;
}
inline int rd(){
int x = 0,f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = x*10+ch-'0';
ch = getchar();
}
return x*f;
}
inline void wt(long long x){
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9) wt(x/10);
putchar(x%10+'0');
}
int main(){
// freopen("T1.in","r",stdin);
ios::sync_with_stdio(false);
cin.tie(0);
n = rd();
for(int i = 1;i <= n;++i) c[i] = rd();
for(int i = 1;i <= n;++i) v[i] = rd();
for(int i = 1;i <= n;++i) f[i] = rd();
for(int i = 1;i <= n;++i){
lst[c[i]] = i;
if(pre[c[i]]) continue;
pre[c[i]] = i;
}
for(int i = 1;i <= n;++i){
mx = 0;
for(int j = i;j <= n;++j){
mx = max(mx,lst[c[j]]);
if(pre[c[j]] < i) j = n+1;
else if(mx == j){
ans = min(ans,calc(i,j));
j = n+1;
}
}
}
wt(ans);
I love coding;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...