题目连接
http://acm.hust.edu.cn/vjudge/problem/440428
Description
小白在玩一个游戏。桌子上有n张多米诺骨牌排成一列。它有k次机会,每次可以选一个还没有倒的骨牌,向左或者向右推倒。每个骨
牌倒下的时候,若碰到了未倒下的骨牌,可以把它推倒。小白现在可以随意设置骨牌的高度,但是骨牌高度为整数,且至少为1,并且
小白希望在能够推倒所有骨牌的前提下,使所有骨牌高度的和最小。
Input
第一行输入一个整数T(1≤T≤101\leq T \leq 101≤T≤10)
每组数据有两行
第一行有两个整数n和k,分别表示骨牌张数和机会次数。(2≤k,n≤1000002\leq k,n\leq 1000002≤k,n≤100000)
第二行有n-1个整数,分别表示相邻骨牌的距离d,1≤d≤1000001\leq d \leq 1000001≤d≤100000
Output
对于每组数据,输出一行,最小的高度和
Sample Input
1
4 2
2 3 4
Sample Output
9
题意
如题…
题解
先把所有的多米诺全部从左往右推倒,每个多米诺的h=距离+1,最后一个骨牌高度为1,算出总的高度H,然后贪心,把在高度最高的骨牌那里截断,即使用一次机会不让骨牌连续推倒,然后依次找次高的骨牌,把机会全部用还。[因为可证如果你可以把机会用给不是最高的骨牌,是H减小一点,那为什么不把机会给更高的骨牌,H减小更多]。最坑的,机会居然可以比骨牌数量还多!坑坑坑…
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
long long n,k;
scanf("%I64d%I64d",&n,&k);
priority_queue<long long,vector<long long>,less<long long> >s;
long long cnt=0;
for(int i=0;i<n-1;i++)
{
long long t;
scanf("%lld",&t);
cnt+=t+1;
s.push(t);
}
if(k>n)
{
printf("%d\n",n);
continue;
}
cnt++;
for(int i=0;i<k-1;i++)
{
long long t=s.top();
s.pop();
cnt-=t;
}
printf("%I64d\n",cnt);
}
return 0;
}