九度 题目1251:序列分割

题目描述:

一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
  比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1;
  {3,6}{2,4,3} m=2
  {3,3}{2,4}{6} m=3 所以m的最大值为3。

输入:

存在多组数据,每组数据一定行为一个正整数n(n<=64),第二行为n个数字。当n为0时,测试结束。

输出:

输出最大值m。

样例输入:
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
样例输出:
4 
2

//

最近懒癌又发作了难过

  数字分组要从数组最大的元素开始分配,因为一般来说,最大元素配成一组选择的范围要小于至多等于稍小的元素,所以代码如下:



        if(msum[m]==mv)//当前分组刚好符合要求,进行下一组分配
              if(rev(v,i+1,msum,m,mv))//表面当前元素能被接纳,所以可以进行下一个元素分组
                msum[m]+=v[i];
        • #include<iostream>
          #include<string.h>
          using namespace std;
          bool ga;
          bool used[65];
          int n;
          bool rev(int*v,int vlen,int*msum,int m,int mv)//msum是用来记录当前分组的和是多少,m是当前第几个分组(从大到小),mv表示每个分组和的最大值
          {   
              if(m==0)//已经将所有元素分配好了
              {
                  ga=true;
                  return true;
              }
                  return rev(v,0,msum,m-1,mv);//当前分组刚好符合要求,进行下一个分组
           
              int i;
              for(i=vlen;i<n;i++)
              {
                  if(used[i]||msum[m]+v[i]>mv)//将没分配过的元素分配到当前组溢出,表明此分配不适合,下一个接着分配
                      continue ;
                  used[i]=true;
                  {
                      ga=true;
                       return true;
                  }
                  msum[m]-=v[i];
                  used[i]=false;
           
                  //if(msum[m]-v[i]==0)//最大的已经试过了
                      //break;
                  if(msum[m]==0)
                      break;
                  while(i<n-1&&v[i]==v[i+1])
                      i++;
              }
              return false;
          }
           
          int main()
          {
               
              while(cin>>n&&n!=0)
              {
                  int v[65];
                  int j,k,i,temp,sum;
                  for(j=0;j<n;j++)//这里的排序感觉效率不佳,可以用sort函数
                  {
                      if(j==0)
                      {
                          cin>>v[0];
                          sum=v[0];
                      }
                      else
                      {
                          cin>>v[j];
                          sum+=v[j];
                          for(k=0;k<j;k++)
                              if(v[j]>v[k])
                                  break;
                          temp=v[j];
                          for(i=j;i>k;i--)
                              v[i]=v[i-1];
                          v[k]=temp;
                      }
                  }
                  int msum[65]={0};
                  ga=false;
                  for(j=(sum/v[n-1])<n?(sum/v[n-1]):n;j>1;j--)
                  if(sum%j==0)
                  {
                      memset(used,0,sizeof(used));
                      memset(msum,0,sizeof(msum));
                      rev(v,0,msum,j,sum/j);
                      if(ga)
                      {
                          cout<<j<<endl;
                          break;
                      }
                  }
           
                  if(!ga)
                      cout<<1<<endl;
              }
              return 0;
           
          }
          /**************************************************************
              Problem: 1251
              User: 午夜小白龙
              Language: C++
              Result: Accepted
              Time:10 ms
              Memory:1520 kb
          ****************************************************************/


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

        “相关推荐”对你有帮助么?

        • 非常没帮助
        • 没帮助
        • 一般
        • 有帮助
        • 非常有帮助
        提交
        评论
        添加红包

        请填写红包祝福语或标题

        红包个数最小为10个

        红包金额最低5元

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

        抵扣说明:

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

        余额充值