完美世界2017秋招真题 【编程题】小萌的烹饪生涯(C++)

题目地址:http://exercise.acmcoder.com/online/online_judge_ques?ques_id=3358&konwledgeId=157

题目:

游戏漫长的前夕版本让无聊的小萌越发的无聊了……为了打发无聊的时间,有效的利用月卡优势,小萌打算开始练习烹饪技能。
现在小萌要做N个食物,第i个食物需要a[i]个单位的肉,现在小萌把肉买来了,是一整块的,他发现每次切肉都要消耗活力,
消耗值等于切的肉的大小:比如肉大小为21个单位,那么小萌切一次则消耗了21点活力。小萌的刀法非常好,
能准确的切分任何他想要的单位的肉,现在小萌想知道,要将这块肉分成他想要的N份,最少需要多少活力。
(买来的肉的大小等于N块肉之和)								


提供一种超时但是正确的解法(60%通过,剩下的超时),希望如果有更好的方法请留言告诉我,超时坑爬不出来了/(ㄒoㄒ)/~~~

思路(分治):

一个序列0...n,将它分为0...cutIndex,cutIndex+1,...,n两部分,cutIndex选取可以使得两部分子序列和的差值最小的位置。每次将序列分为两部分,让两部分子序列和尽量相近,这样就分成了两个较小的子问题。result存储需要的活力值,如果切分前的序列长度大于2,需要切分,result增,如果切分前的序列长度等于1,退出递归。

#include "iostream"
#include "vector"
#include "algorithm"
using namespace std;
int result = 0;
int findCut(vector&vc,int startIndex,int endIndex)
{
    int cutIndex = 0;
    if(endIndex-startIndex<=1)//len <= 2
    {
        cutIndex = startIndex;
        return cutIndex;
    }
    int sum = 0;
    for(int i=startIndex;i<=endIndex;i++)
    {
        sum+=vc[i];
    }
    int halfSum = sum/2;
    int sumTemp = 0,sumTemp2 = 0;
    for(int i=startIndex;i<=endIndex;i++)
    {
        sumTemp+=vc[i];
        sumTemp2 = sumTemp + vc[i+1];

        if(sumTemp<=halfSum&&sumTemp2>halfSum) {
            //cutIndex是0~cutIndex总和刚好小于或者刚刚大于halfSum的值,关键在于两边和差最小
            if (abs((sum - sumTemp) - sumTemp) < abs((sum - sumTemp2) - sumTemp2)) {
                cutIndex = i;
                return cutIndex;
            } else {
                cutIndex = i + 1;
                return cutIndex;
            }
        }
    }
}

void countArray(vectorvc,int start,int end)
{
//    cout<<"start:"<=2
    {
        result+=vc[i];
    }
    countArray(vc,start,cutI);
    countArray(vc,cutI+1,end);
}
int main()
{
    int N;
    cin>>N;
    vectorvc;
    for(int i=0;i>inNum;
        vc.push_back(inNum);
    }
    sort(vc.begin(),vc.end());
    countArray(vc,0,vc.size()-1);
    cout<


你可能感兴趣的:(笔试面试)