题目链接:Problem - C - Codeforces
题目:
我有n个朋友,商店有m种商品,这m种商品按序号价格从小到大排列,对于每一个朋友我给出一个序号k,我可以直接给朋友序号k的商品价格的金钱或给朋友买一个序号小于等于k的商品,且每种商品最多只能买一次,问我需要花费的最少金钱?
分析:
此题有一个很重要的信息,就是c[i] < c[i + 1] < c[i + 2] ,所有的c[]值输入时就是升序排列的。
所以我们可以将k[]进行从小到大的排序。
并且从后往前进行取值,
因为k[i]小的可以取k[i]对应的值,而k[i]小,对应的c[k[i]]值就小。
而k[i]大的。如果1~k[i]都取过了,那么就只能取k[i].
所以我们从后往前,k[i]大的则取小值。如果被取了就取k[i],k[i]小的如果到时候被取了则就取k[i]即可。
代码实现:
# include <iostream>
# include <algorithm>
using namespace std;
const int N = 3e5 + 10;
int k[N];
int c[N];
int t,n,m;
int main()
{
scanf("%d",&t);
while(t--)
{
long long ans = 0;
int cnt = 1; // 当前可以取第cnt个了
scanf("%d %d",&n,&m);
for(int i = 1 ; i <= n ; i++)
{
scanf("%d",&k[i]);
}
for(int i = 1 ; i <= m ; i++)
{
scanf("%d",&c[i]);
}
sort(k + 1 , k + 1 + n);
for(int i = n ; i >= 1 ; i--)
{
if(cnt <= k[i])
{
ans += c[cnt++];
}
else
{
ans += c[ k[i] ];
}
}
printf("%lld\n",ans);
}
return 0;
}