问题描述
提示:这里描述项目中遇到的问题:
有nn陷阱编号从11自nn.您将按顺序逐个浏览它们。这我我-第 0 个陷阱交易一个我ai基地伤害你。
与其经历陷阱,不如把它跳过。您最多可以跳过kk陷阱。如果你跳过一个陷阱,它不会对你造成任何伤害。但是还有一个额外的规则:如果你跳过一个陷阱,所有下一个陷阱的伤害都会增加11(这是一个额外的伤害)。
请注意,如果你跳过陷阱,你不会得到任何伤害(基础伤害和奖励伤害都没有)。此外,额外伤害也会叠加,例如,如果你通过陷阱我我基础损坏一个我ai,并且您已经跳过了33陷阱,你得到(一个我+3)(一个i+3)损伤。
你必须找到最小的伤害,如果你被允许跳过不超过kk陷阱。
输入由多个测试用例组成。第一行包含单个整数tt (1≤吨≤1001≤吨≤100) — 测试用例的数量。测试用例的说明如下。
每个测试用例的第一行包含两个整数nn和kk (1≤n≤2⋅1051≤n≤2⋅105,1≤ 千≤1≤ 千≤) — 陷阱的数量和允许你进行的跳跃次数。
每个测试用例的第二行包含nn整数一个1,一个2,...,一个na1,a2,...,an (1≤一个我≤1091≤ai≤109) — 所有陷阱的基本伤害值。
保证nn所有测试用例不超过2⋅1052⋅105.
对于每个测试用例输出一个整数 - 如果您被允许跳过不超过k陷阱。 }
题目分析:
我们通过题目可以知道跳过一次陷阱,会导致后边陷阱伤害增加,那么我们可以将跳过该陷阱导致后续的伤害一起转移到该陷阱上,然后我们按照造成伤害的大小排序,去掉最大造成伤害的陷阱即可
代码:
- #include<iostream>
- #include <algorithm>
- #include <vector>
- using namespace std;
- const int N=4e5+10;
- typedef pair<int,int>PII;
- PII p[N]; int n,k;
- bool cmp(PII a,PII b)
- {
- return a.first-(n-a.second)>b.first-(n-b.second);
- }
- int main ()
- {
- int t;
- cin>>t;
- while(t--)
- {
- cin>>n>>k;
- long long sum=0;
- for(int i=1;i<=n;i++)
- {
- cin>>p[i].first;
- sum+=p[i].first;
- p[i].second=i;
- }
- sort(p+1,p+n+1,cmp);
- long long ct=0;
- for(int i=1;i<=k;i++)
- {
- sum-=p[i].first-(n-p[i].second);sum-=ct;
- ct++;
- }
- cout<<sum<<endl;
- }
- }
- 题目选自
- https://codeforces.com/contest/1684/my