【BZOJ 2006】 [NOI2010]超级钢琴

2006: [NOI2010]超级钢琴

Time Limit: 20 Sec   Memory Limit: 552 MB
Submit: 1535   Solved: 737
[ Submit][ Status]

Description

小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐。 这架超级钢琴可以弹奏出n个音符,编号为1至n。第i个音符的美妙度为Ai,其中Ai可正可负。 一个“超级和弦”由若干个编号连续的音符组成,包含的音符个数不少于L且不多于R。我们定义超级和弦的美妙度为其包含的所有音符的美妙度之和。两个超级和弦被认为是相同的,当且仅当这两个超级和弦所包含的音符集合是相同的。 小Z决定创作一首由k个超级和弦组成的乐曲,为了使得乐曲更加动听,小Z要求该乐曲由k个不同的超级和弦组成。我们定义一首乐曲的美妙度为其所包含的所有超级和弦的美妙度之和。小Z想知道他能够创作出来的乐曲美妙度最大值是多少。

Input

第一行包含四个正整数n, k, L, R。其中n为音符的个数,k为乐曲所包含的超级和弦个数,L和R分别是超级和弦所包含音符个数的下限和上限。 接下来n行,每行包含一个整数Ai,表示按编号从小到大每个音符的美妙度。

Output

只有一个整数,表示乐曲美妙度的最大值。

Sample Input

4 3 2 3

3

2

-6

8

Sample Output

11

【样例说明】
共有5种不同的超级和弦:

音符1 ~ 2,美妙度为3 + 2 = 5
音符2 ~ 3,美妙度为2 + (-6) = -4
音符3 ~ 4,美妙度为(-6) + 8 = 2
音符1 ~ 3,美妙度为3 + 2 + (-6) = -1
音符2 ~ 4,美妙度为2 + (-6) + 8 = 4
最优方案为:乐曲由和弦1,和弦3,和弦5组成,美妙度为5 + 2 + 4 = 11。

HINT

Source


堆+RMQ


定义一个四元组(i,l,r,t)表示是以第i个为开头的,结尾在l-r之间(满足长度>=L,<=R),且结尾在t的权值和最大。


首先把以每一位开头的四元组加入堆,此时的l,r是恰好满足长度>=L,<=R;


堆中排序的关键字是权值之和。


然后把堆顶取出(i,l,r,t),然后再把(i,l,t-1,t')和(i,t+1,r,t'')加入堆中(因为要满足任意两个序列不同的条件)


那么四元组中的t如何快速求出?


用RMQ即可:维护前缀和,权值和就是sum[t]-sum[i-1],对于用一个四元组sum[i-1]相同,因此只要找到l-r中sum[i]最大的即可。


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#define mp(a,b,c,d) (data){a,b,c,d}
#define inf 100000000
#define LL long long
#define M 500005
struct data
{
	int i,l,r,t;
};
using namespace std;
int a[M],Log[M],f[M][20],n,k,l,r;
LL ans=0LL;
void RMQ()
{
	for (int i=1;i<=n;i++)
		f[i][0]=i;
	for (int j=1;(1<<j)<=n;j++)
		for (int i=1;i+(1<<j)-1<=n;i++)
		{
			int x1=f[i][j-1],x2=f[i+(1<<(j-1))][j-1];
			f[i][j]=a[x1]>a[x2]?x1:x2;
		}
	Log[0]=-1;
	for (int i=1;i<=n;i++)
		Log[i]=Log[i>>1]+1;
}
inline int Query(int l,int r)
{
	if (l==r) return l;
	int t=Log[r-l+1];
	int x1=f[l][t],x2=f[r-(1<<t)+1][t];
	return a[x1]>a[x2]?x1:x2;
}
inline bool operator <(data x,data y)
{
	return a[x.t]-a[x.i-1]<a[y.t]-a[y.i-1];
}
void Solve()
{
	priority_queue<data,vector<data> > q;
	for (int i=1;i<=n;i++)
		if (i+l-1<=n)
		{
			int x=min(n,i+r-1);
			q.push(mp(i,i+l-1,x,Query(i+l-1,x)));
		}
	for (int i=1;i<=k;i++)
	{
		data x=q.top();
		q.pop();
		ans+=(a[x.t]-a[x.i-1]);
		if (x.t-1>=x.l) q.push(mp(x.i,x.l,x.t-1,Query(x.l,x.t-1)));
		if (x.t+1<=x.r) q.push(mp(x.i,x.t+1,x.r,Query(x.t+1,x.r)));
	}
}
int main()
{
    scanf("%d%d%d%d",&n,&k,&l,&r);
	a[0]=0;
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]),a[i]+=a[i-1];
	RMQ();
	Solve();
	printf("%lld\n",ans);
	return 0;
}



感悟:

1.RE是因为>>写成<<


2.感觉这道题和wc第一题有点相似。。非常巧妙~堆中每次删除一个加入两个,保证堆中元素是O(n)的

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值