当前位置: 首页 > news >正文

《算法笔记》11.8小节——动态规划专题->总结 问题 A: 第二题

题目描述

一个数组中有若干正整数,将此数组划分为两个子数组,使得两个子数组各元素之和a,b的差最小,对于非法输入应该输出ERROR。

输入

数组中的元素

输出

降序输出两个子数组的元素和

样例输入
10 20 30 10 10
10 20 abc 10 10
样例输出
40 40
ERROR

分析:这道题虽然没给数据范围,但是根据提交后的结果,大概可以判断由于给出的元素和数量级在 10 的 8 次方左右,数据过大,无法使用动态规划的方法解决。可以使用折半枚举的方法来完成这道题。

将原数组拆成两半,枚举前半部分的所有子集和,存入数组并排序;枚举后半部分所有子集和,然后在前半数组的子集和中用二分搜索,找到最接近总和一半的组合。

#include<algorithm>
#include <iostream>
#include  <cstdlib>
#include  <cstring>
#include   <string>
#include   <vector>
#include   <cstdio>
#include    <queue>
#include    <stack>
#include    <ctime>
#include    <cmath>
#include      <map>
#include      <set>
#define INF 0x3fffffff
#define db1(x) cout<<#x<<"="<<(x)<<endl
#define db2(x,y) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<endl
#define db3(x,y,z) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<endl
#define db4(x,y,z,r) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<", "<<#r<<"="<<(r)<<endl
#define db5(x,y,z,r,w) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<", "<<#r<<"="<<(r)<<", "<<#w<<"="<<(w)<<endl
using namespace std;int main(void)
{#ifdef testfreopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);clock_t start=clock();#endif //testchar s[1000];while(fgets(s,1000,stdin)){int len=strlen(s),t=0,f=1,sum=0;vector<int>num;for(int i=0;i<len;++i){int index;for(index=i;index<len;++index){if(s[index]==' '||s[index]=='\n')break;else if(!isdigit(s[index])){f=0;break;}}if(!f)break;int temp=0;for(int j=i;j<index;++j){temp=temp*10+s[j]-'0';}
//            db1(temp);i=index;sum+=temp;num.push_back(temp);}if(!f){printf("ERROR\n");continue;}int n=num.size(),n1=n-n/2,n2=n-n1,ret=sum,m1=1<<n1,m2=1<<n2;int cnt[1<<15]={0};for(int i=0;i<m1;++i){int j,k;for(j=k=0;j<n1;++j)if(i&(1<<j))k+=num[j];cnt[i]=k;}sort(cnt,cnt+m1);int l=0,r=m1;for(int i=0;i<m2;++i){int j,k;for(j=k=0;j<n2;++j)if(i&(1<<j))k+=num[n1+j];l=0,r=m1;while(l<r){int temp=k+cnt[(l+r)/2];if(temp<sum-temp)l=(l+r)/2+1;else r=(l+r)/2;}if(l<m1&&k+cnt[l]-(sum-k-cnt[l])<ret)ret=k+cnt[l]-(sum-k-cnt[l]);if(l>0&&sum-k-cnt[l-1]-k-cnt[l-1]<ret)ret=sum-k-cnt[l-1]-k-cnt[l-1];}printf("%d %d\n",(sum+ret)/2,(sum-ret)/2);}#ifdef testclockid_t end=clock();double endtime=(double)(end-start)/CLOCKS_PER_SEC;printf("\n\n\n\n\n");cout<<"Total time:"<<endtime<<"s"<<endl;        //s为单位cout<<"Total time:"<<endtime*1000<<"ms"<<endl;    //ms为单位#endif //testreturn 0;
}

http://www.xdnf.cn/news/556057.html

相关文章:

  • OSA实战笔记一
  • LLM笔记(十一)常见解码/搜索算法
  • canvas浅析(一)
  • Java 09Stream流与File类
  • ragas precision计算的坑
  • 使用frp内网穿透本地的虚拟机
  • 几款常用的虚拟串口模拟器
  • springboot+vue3实现在线购物商城系统
  • MS16-075 漏洞 复现过程
  • Ai学习之openai api
  • 武汉火影数字|数字展厅展馆制作:沉浸式体验,全方位互动
  • Vue 3 深度解析:Composition API、Pinia状态管理与路由守卫实战
  • Rocketmq leader选举机制,通过美国大选解释
  • 第32节:基于ImageNet预训练模型的迁移学习与微调
  • 【MySQL】第六弹——表的CRUD进阶(四)聚合查询(下)
  • 图的几种存储方法比较:二维矩阵、邻接表与链式前向星
  • 人工智能驱动的制造业智能决策:从生产排程到质量闭环控制
  • 深度学习-mmcv中build_runner实例化全流程详解
  • EtherCAT通信协议
  • 【Netty】- NIO基础2
  • 易境通海外仓系统PDA蓝牙面单打印:解锁库内作业新姿势
  • 【MySQL成神之路】运算符总结
  • day 31
  • STM32之定时器(TIMER)与脉冲宽度调制(PWM)
  • Glasgow Smile: 2靶场渗透
  • PostGIS栅格数据类型解析【raster】
  • 【深入理解索引扩展—1】提升智能检索系统召回质量的3大利器
  • 详解ip地址、子网掩码、网关、广播地址
  • 系统编程的标准IO
  • 【LINUX操作系统】日志系统——自己实现一个简易的日志系统