• (泡泡大作战)二分枚举答案


    球球大作战

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 92    Accepted Submission(s): 31


     

    Problem Description

    小Z最近迷上了球球大作战,他准备出一个与球球大作战相似的题目来考考大家。现在有n个球依次排列在一条直线上,每个球有其对应的体积。每次合并操作可以将任意相邻两个球合并为一个球,合并之后的球的体积为这两相邻球体积之和。现在有m次合并,经过这m次合并之后,希望剩下球中体积的最小值能够最大(采用最佳合并策略)。

     

    Input

    输入一个T,代表数据的组数。(T<=10)
    第二行包含两个正整数N,M,表示N个球,M次合并机会。
    接下来一行为n个正整数x[1], x[2], … ,x[n],其中x[i]表示编号为i的球的体积。
    数据范围:1≤M<N≤100000,1≤x[i]≤100000。

     

    Output

    对于每个测试样例,输出一行,包含一个整数,m次合并之后的剩下的球的体积的最小值最大是多少。每个测试样例占一行。

     

    Sample Input

    
     

    2

    4 2

    4 2 3 5

    6 3

    1 7 2 2 5 9

     

    Sample Output

    
     

    6 8 Hint: 第一组样例: 合并4、2得到{ 6 3 5 },合并3、5得到{ 6 8 },最小值为6。 也可以这样进行合并,合并2、3得到{ 4 5 5 },合并4、5得到{ 9 5 },最小值为5,但最小值小于上面的合并方案。 第二组样例: 合并1、7得到 { 8 2 2 5 9 },合并2、2得到 { 8 4 5 9 },合并4、5得到 { 8 9 9 },最小值为8。

     

    答案肯定在0 到 (所有和) 之间  且最小值与 合并次数成正相关

    所以枚举答案就行了

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int maxn=1e5+10;
    int pp[maxn];
    int t,k,n;
    int initl,initr;
    int F(int val)//算出最小值为val最少需要合并的次数
    {
        int addval=0;
        int ans=0;
        for(int i=0;i<n;++i)
        {
            if(pp[i]+addval<val)
            {
                ans++;
                addval+=pp[i];
            }
            else
            {
                addval=0;
            }
        }
        return ans;
    }
    int erfen()
    {
        int l=initl;
        int r=initr;
        int mid,ans;
        while(l<=r)//枚举合并的最小值
        {
            mid=(l+r)/2;
            if(F(mid)<=k)//保证都满足的情况下 取最大
            {
                l=mid+1;
                ans=mid;
            }
            else
            {
                 r=mid-1;
            }
        }
        return ans;
    }
    /*
    -----*****-----
      -1   0    1
    */
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            initl=0;
            initr=0;
            scanf("%d %d",&n,&k);
            for(int i=0;i<n;++i)
            {
                 scanf("%d",pp+i);
                 initr+=pp[i];
            }
            int ans=erfen();
            printf("%d
    ",ans);
        }
    }
    

    a

  • 相关阅读:
    第1章 游戏之乐——NIM(3)两堆石头的游戏
    NFS介绍和安装
    shell脚本删除N天前的目录-----附linux和mac上date命令的不同
    关于子线程更新UI
    WIN7下安装SVNserver端及client搭建协作环境
    Selenium_WebDriver登录模拟鼠标移动切换窗体等操作练习(cssSelector初练手)_Java
    UICollectionView具体解释
    局域网使用的IP地址范围
    hdu 2955 Robberies
    POJ 1661 Help Jimmy(DP,注意边界)
  • 原文地址:https://www.cnblogs.com/dchnzlh/p/10427306.html
Copyright © 2020-2023  润新知