思路:上式右边是常量,所以最小化左边即可,在两个数的ti可以交换的情况下,如ci*ti,cj*tj,若有ti < tj 且 ci < cj,那么交换ti和tj能获得更优解,作差即可验证,所以贪心策略是c越小的数选择越大的t,由于题目限定要ti > i,从小到大处理用set维护一个递增的序列即可。
# include <bits/stdc++.h>
# define mp make_pair
# define pb push_back
# define A first
# define B second
using namespace std;
typedef long long LL;
const int maxn = 3e5+3;
set<pair<int,int> >s;
int ans[maxn];
int main()
{
LL sum = 0;
int n, k, a;
scanf("%d%d",&n,&k);
for(int i=1; i<=n; ++i)
{
scanf("%d",&a);
s.insert(mp(a, i));
if(i >= k+1)
{
auto t = s.end(); --t;
ans[t->B] = i;
sum = sum + 1LL*(i-t->B)*t->A;
s.erase(t);
}
}
for(int i=1; i<=k; ++i)
{
auto t = s.end(); --t;
ans[t->B] = n+i;
sum = sum + 1LL*(i+n-t->B)*t->A;
s.erase(t);
}
printf("%lld\n",sum);
for(int i=1; i<=n; ++i) printf("%d ",ans[i]);
puts("");
return 0;
}