题目链接:[http://codeforces.com/problemset/problem/853/A]
分析:
记代价为totv,则
totv=∑(b[i]−a[i])∗v[i]=∑b[i]∗v[i]−∑a[i]∗v[i]
t
o
t
v
=
∑
(
b
[
i
]
−
a
[
i
]
)
∗
v
[
i
]
=
∑
b
[
i
]
∗
v
[
i
]
−
∑
a
[
i
]
∗
v
[
i
]
(其中
b[i]≥a[i]
b
[
i
]
≥
a
[
i
]
),因为
∑a[i]∗v[i]
∑
a
[
i
]
∗
v
[
i
]
为定值,要使totv最小,则
∑b[i]∗v[i]
∑
b
[
i
]
∗
v
[
i
]
最小。
故,贪心策略为让
v[i]
v
[
i
]
大的先选择时间
b[i]
b
[
i
]
—— 离
a[i]
a
[
i
]
最近的大于
a[i]
a
[
i
]
的时间。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e5+100;
struct node
{
int x,v;
}a[maxn];
set <int> s;
int n,k,b[maxn];
long long ans;
bool cmp(node s,node t)
{
return s.v>t.v;
}
int main()
{
scanf("%d %d",&n,&k);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i].v);
a[i].x = i;
s.insert(i+k);
}
sort(a+1,a+n+1,cmp);
set<int>::iterator it;
for (int i=1;i<=n;i++)
{
it = s.lower_bound(a[i].x);
b[a[i].x] = *it;
ans += (long long)(*it - a[i].x)*a[i].v;
s.erase(it);
}
printf("%I64d\n",ans);
for (int i=1;i<=n;i++) printf("%d ",b[i]);
return 0;
}