你看到标题一定很懵逼,其实我也很懵逼,主要是我也不知道这题应该叫什么(逃)
【思路】:
用 f[l][r]来表示区间l到r的的和。
因为区间是非负的所以很明显f[l][r+1]一定大于f[l][r]
举个栗子:
区间:17 1 5 6 78 9
f[2][4]=1+5+6=12
f[2][5]=1+5+6+78=f[2][4]+78=90
同理:
S[l,r]<=S[l-1,r]
用堆维护,先加入[1,1],[2,2]...[n,n]所有区间 然后每次取出一个最小的区间[l,r] 如果l!=1&&[l-1,r]没有用过,则加入堆中 如果r!=n&&[l,r+1]没有用过,则加入堆中
但是该怎么知道一个区间用过没有呢?
只需要将区间看成pair<int ,int >就ok了,再用map<pair<int ,int >,bool>判重
【代码】:by 涛哥
#include<utility> #include<map> #include<queue> #include<cstdio> #include<iostream> using namespace std; int k, n, a[100001]; priority_queue< pair<int, pair<int, int> > > q; map<pair<int, int> , bool>m; int main() { cin >> n >> k; for(int i = 1; i <= n; ++i) { scanf("%d", &a[i]); q.push(make_pair(-a[i],make_pair(i,i))); } for(int i = 1; i <= k; ++i) { cout <<-1 * q.top().first << ' '; int l = q.top().second.first; int r = q.top().second.second; int g = q.top().first; q.pop(); if(!m[make_pair(l-1,r)]) { if(l != 1) q.push(make_pair(g - a[l-1],make_pair(l-1,r))); m[make_pair(l-1,r)] = 1; } if(!m[make_pair(l,r+1)]) { if(r != n) q.push(make_pair(g - a[r+1],make_pair(l,r+1))); m[make_pair(l,r+1)] = 1; } } return 0; }
稍稍结胡思一下:
pair会默认first是排序的依据(woc)