题解 | #小黑的区间#

小紫的总分

https://ac.nowcoder.com/acm/contest/84244/A

D.小黑的区间

这题官方是用双指针做的,也是这题的一个很标准的做法,但比赛时笔者想到了用dp做的方法,觉得很不错,所以分享一波。

首先我们知道,对于一个区间[1,2,3]来说,如果想求其中有几个完美区间,显然是[1],[2],[3],[1,2],[2,3],[1,2,3]共六个,那么如果再加入一个4呢?答案是会多出[1,2,3,4],[2,3,4],[3,4],[4],共四个,加起来十个。那对于区间[1,2]呢?显然是[1],[2],[1,2]共三个。

如果观察能力强的同学可能会发现,对于一个区间a来说,每增加一个数,如果该区间仍是完美区间,那么完美区间的总个数=原来完美区间的个数+区间长度,即有dp[i]=dp[i-1]+len;

显然,加入的数如果和上一个相同的数距离大于k,就不是完美区间,此时只要用一个桶b来装各个数的最新位置,然后利用桶把区间长度减小即可。 接下来上代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
using pii = pair<int, int>;
using i64 = int64_t;
const int N = 1e5 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const double pi = 3.1415926535;


ll dp[N], b[N];  //记得开ll,不然会WA

void solve() {
	ll n, k;
	cin >> n >> k;
	ll len = 0;
	for (ll i = 1; i <= n; i++) {
		ll x;
		cin >> x;
		if (!b[x] || i - b[x] <= k || i - 1 - len > b[x]) {  //这里第三个条件是判断当
			len++;                                           //前的区间是否已经减去上
			b[x] = i;                                        //一个x,这样就不用改区间
			dp[i] = dp[i - 1] + len;                         
		} else {
			len = len + 1 - (b[x] - (i - 1 - len));         //修改区间大小
			b[x] = i;
			dp[i] = dp[i - 1] + len;
		}
	}
	cout << dp[n];
}

int main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int _ = 1;
	//cin >> _;
	while (_--)
		solve();

	return 0;
}

好了,这篇题解就到这里。我知道可能修改区间那里有点抽象,但本蒟蒻也想不到更合适的说法qwq,这是在下第一篇题解,希望各位观看愉快,如有问题欢迎讨论~

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-07 12:04
毕业生招你惹你了,问一个发薪日来一句别看网上乱七八糟的你看哪个工作没有固定发薪日扭头就取消了面试就问了一句公司都是这个态度吗还搞上人身攻击了...
程序员小白条:呃呃呃,都还没面试,我都不会问这么细,何况通不通过,去不去都另说,你没实力和学历的话,在外面就这样,说实话没直接已读不回就不错了,浪费时间基本上
点赞 评论 收藏
分享
点赞 评论 收藏
分享
nus2201602...:兄弟,你这个简历撕了丢了吧,就是一坨,去找几个项目,理解项目流程,看几遍就是你的了,看看八股就去干了,多看看牛客里别人发出来的简历,对着写,你这写的啥啊,纯一坨
点赞 评论 收藏
分享
哈哈哈哈哈哈哈哈哈哈这个世界太美好了
凉风落木楚山秋:毕业出路老师不管,你盖个章他好交差就完事了,等你盖完毕业了就不关他事情了
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务