移除石子使总数最小

移除石子使总数最小

给你一个整数数组 piles ,数组 下标从 0 开始 ,其中 piles[i] 表示第 i 堆石子中的石子数量。另给你一个整数 k ,请你执行下述操作 恰好 k 次:

选出任一石子堆 piles[i] ,并从中 移除 floor(piles[i] / 2) 颗石子。

注意:你可以对 同一堆 石子多次执行此操作。

返回执行 k 次操作后,剩下石子的 最小 总数。

floor(x) 为 小于 或 等于 x 的 最大 整数。(即,对 x 向下取整)。
在这里插入图片描述
对于这个题目,最简单的做法,就是直接每次取一次最大值,然后更新一次序列,但是算法时间并不能通过要求,如果排序之后在进行操作,也不能通过,不过下面算法思想是正确的,额可以借鉴。

int max_index(int *p,int size){
    int i=1;
    int m=p[0];
    int po=0;
    for(i;i<size;i++){
        if(m<p[i]){ 
            m=p[i];
            po=i;
        }
    }
    return po;
}


int minStoneSum(int* piles, int pilesSize, int k){
    int i=0;
    int index;
    int sum=0;
    for(i;i<k;i++){
       
        index =max_index(piles,pilesSize);
      //   printf("%d ",index);
        piles[index]=piles[index]-floor(piles[index]/ 2);
    }
    for(i=0;i<pilesSize;i++){
        sum=sum+piles[i];
    }
    return sum;
}

那么,该怎么办呢,于是有了下面这个算法,如果数都不大的话,我们可以直接将数存储在一个大的数组中,并且下标就为其数据值,然后,我们就可以从上往下进行遍历,同时可能出翔相同的值,那么,我们可以统计一下数据元素个数,为零的时候,我们才进行下次遍历。

int minStoneSum(int* piles, int pilesSize, int k){
    int hash[10001] = {0};
    for (int i = 0; i < pilesSize; i++) {
        hash[piles[i]]++;
    }
    for (int i = 10000; i > 0; i--) {
        if (hash[i] > 0) {
            hash[i]--;
            int temp = i - floor(i / 2);
            hash[temp]++;
            i++;
            k--;
        } 
        if (k == 0) {
            break;
        }
    }
    
    int ans = 0;
    for (int i = 0; i < 10001; i++) {
        if (hash[i] != 0) {
            ans += hash[i] * i;
        }
    }
    return ans;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值