试题 算法训练 搬走要石

Posted ~晚风微凉~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了试题 算法训练 搬走要石相关的知识,希望对你有一定的参考价值。

资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
  住在有顶天的天人Tensi对自己的住处很不满。终于有一天她决定把门前碍眼的要石通通丢掉(怒扔要石)。控制要石自然是很容易的事,不过也会消耗灵力。假设搬走一块质量为1的要石会消耗1点灵力,而且由于要石都是连着放置的缘故所以每次除了搬走一颗,也可以搬走连续的任意数量的要石,自然质量是算在一起的。现在Tensi准备最多使用M次灵力,但是她太懒……所以每次只会使用同量的灵力, 也因为她太烂,所以也不愿意多花一点灵力……现在很懒的Tensi需要你帮她计算最少一次需要消耗多少灵力,能够在M次内把所有要石都丢到人间去……
输入格式
  第一行两个数N,M,用一个空格分隔。1<=n<=1000,1<=m<=400
  表示一共有N颗要石需要搬走已经Tensi最多发动M次灵力。
  接下来包括N 个正整数 0<=ai<=40000 顺序表示每一颗要石的质量。
输出格式
  输出一个数T
  表示Tensi 每次至少消耗T灵力。0<=T<=1000000
  如果无解输出-1.
样例输入
5 3
1 2 1 1 1
样例输出
3
数据规模和约定
  对于100%的数据,1<=n<=1000,1<=m<=400,0<=ai<=40000。
  保证0<=T<=1000000。
  
题目标签:二分
思路:可以用二分确定最终的值区间,不断细分。
但是怎么去确定:每次拿的区间长度呢
1.每次灵力一样,可以用前缀和相等

#include<bits/stdc++.h>
using namespace std;
int a[1005],n,m;
int check(int d)

    int sum=0,i=0,cnt=0;

    while(a[i])
    
        if(sum+a[i]<=d)
            sum+=a[i];
            i++;
        
        else if(a[i]>d)return 0;
        else 
            cnt++;
            sum=0;
        
    

    return cnt<m;

int main()

    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d",a+i);
    int l=0,r=1000000;
    int mid;

    while(l<r)
        mid=(l+r)>>1;
        if(check(mid))
            r=mid;
        
        else 
            l=mid+1;
        
    
    printf("%d",l);
    return 0;


check函数很关键。

以上是关于试题 算法训练 搬走要石的主要内容,如果未能解决你的问题,请参考以下文章

(蓝桥杯)试题 算法训练 排列

(蓝桥杯)试题 算法训练 数的计数

(蓝桥杯)试题 算法训练 孪生素数

(蓝桥杯)试题 算法训练 观星

(蓝桥杯)试题 算法训练 加法分解

(蓝桥杯)试题 算法训练 数字反转