hdu 5777 domino【贪心】

domino

Accepts: 462

Submissions: 1498

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 131072/131072 K (Java/Others)

问题描述

小白在玩一个游戏。桌子上有n张多米诺骨牌排成一列。它有k次机会,每次可以选一个还没有倒的骨牌,向左或者向右推倒。每个骨

牌倒下的时候,若碰到了未倒下的骨牌,可以把它推倒。小白现在可以随意设置骨牌的高度,但是骨牌高度为整数,且至少为1,并且

小白希望在能够推倒所有骨牌的前提下,使所有骨牌高度的和最小。

输入描述

第一行输入一个整数T($1\leq T \leq 10$)

每组数据有两行

第一行有两个整数n和k,分别表示骨牌张数和机会次数。($2\leq  k,n\leq  100000$)

第二行有n-1个整数,分别表示相邻骨牌的距离d,$1\leq d \leq 100000$

输出描述

对于每组数据,输出一行,最小的高度和

输入样例

1

4 2

2 3 4

输出样例

9

 

思路:


1、首先我们知道,如果两个骨牌之间间隔为d,那么如果我们将其分配高度的话,我们希望设定一个高度为d+1,另一个为1。


2、那么如果我们有三个骨牌,之间间隔从左到右为d1,d2,而且我们有一次推倒机会的话,我们希望设定一个高度为d1+1,一个高度为d2+1,最后一个为1,那么如果我们有两次推倒机会的话呢?我们就有机会使得那两个高度分别为d2+1,d1+1的骨牌其中一个高度为1,我们让他自己推倒就好,这个时候我们就能引入这个贪心的思想:选其中大的,设定为1,这样我们就能使得最终高度和最小 。


3、那么问题解决的方法就是:将给出的距离排序,去掉k-1个距离最大的那些骨牌,使其设定高度为1,其他的设定高度为di+1,最后一个也设定高度为1.


4、注意K>=n的时候,输出n


Ac代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll __int64
ll a[1000000];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll n,k;
        memset(a,0,sizeof(a));
        scanf("%I64d%I64d",&n,&k);
        for(int i=0;i<n-1;i++)
        {
            scanf("%I64d",&a[i]);
        }
        if(k>=n)
        {
            printf("%I64d\n",n);
            continue;
        }
        ll tmp=k-1;
        ll output=0;
        sort(a,a+n-1);
        for(int i=n-2-tmp;i>=0;i--)
        {
            output+=a[i]+1;
        }
        output+=k;
        printf("%I64d\n",output);
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值