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

买瓜(dfs+剪枝)

题目描述

小蓝正在一个瓜摊上买瓜。瓜摊上共有 n 个瓜,每个瓜的重量为 Ai 。

小蓝刀功了得,他可以把任何瓜劈成完全等重的两份,不过每个瓜只能劈一刀。

小蓝希望买到的瓜的重量的和恰好为 m 。

请问小蓝至少要劈多少个瓜才能买到重量恰好为 m 的瓜。如果无论怎样小蓝都无法得到总重恰好为 m 的瓜,请输出 −1 。

输入格式

输入的第一行包含两个整数 n, m,用一个空格分隔,分别表示瓜的个数和小蓝想买到的瓜的总重量。

第二行包含 n 个整数 Ai,相邻整数之间使用一个空格分隔,分别表示每个瓜的重量。

输出格式

输出一行包含一个整数表示答案。

样例输入

3 10
1 3 13

样例输出

2

提示

对于 20% 的评测用例,∑n≤10;

对于 60% 的评测用例,∑n≤20;

对于所有评测用例,1 ≤n≤30,1≤ Ai ≤ 10^9 ,1 ≤ m ≤ 10^9

思路:

使用深度优先搜索解决, 对每个瓜的三种选择进行搜索, 解空间树是一颗完全三叉树, 时间复杂度为O(3^n), 肯定会超时, 故需要进行剪枝。

买半个瓜时需要将重量除2,会产生小数,故可以将重量数组都乘2,最大重量也乘2。

搜索时需要记录三个状态,当前层数pos,当前总重量sum,当前劈瓜的次数cnt,以下情况需要剪枝:
1)当前劈瓜次数大于已求得的最小次数,即cnt>ans
2)当前重量之和大于要求的重量,即sum>m

但是这样仍然会超时,还可以将重量数组降序排列,使得更快剪枝。还可以创建一个重量数组的后缀数组suf,这样在搜索时可以利用其剪枝:若当前重量加上剩余的所有瓜重量之和小于要求的重量,剪枝。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=33;
double a[N];
double s[N]; 
bool st[N];
int n;
double m;
int cnt=1e9;
//三种状态 整个 一半 不要
//dfs+剪枝 
//参数 当前层数 当前的西瓜的总重量 当前切了多少次 
void dfs(int pos,double sum,int num)
{//当sum==m时 取最小的 返回上一层 if(sum==m){cnt=min(cnt,num);return ;}//剪枝 sum+s[n]-s[pos-1] 是求当前sum加上之后所有的数均不能组成时 剪枝一下 if(sum>m||pos>n||cnt<=num||sum+s[n]-s[pos-1]<m) return ;dfs(pos+1,sum+a[pos],num);//整个要 dfs(pos+1,sum+(a[pos]/2),num+1);//半个 dfs(pos+1,sum,num);//都不要 
}
//从大到小排 尽量减少切一半的次数 
double cmp(double x,double y)
{return x>y;} 
int main()
{cin>>n>>m;for(int i=1;i<=n;i++) {cin>>a[i];}//排序 从大到小排 sort(a+1,a+1+n,cmp);//求前缀和 for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];dfs(1,0,0);if(cnt==1e9) cout<<"-1"<<endl;else cout<<cnt<<endl; return 0;
}

 

相关文章:

  • 安卓Java面试题 51-60
  • OxyPlot图表曲线图学习笔记(winform)
  • python基础及网络爬虫
  • C语言第三十七弹---文件操作(下)
  • 【新手适用】手把手教你从零开始实现一个基于Pytorch的卷积神经网络CNN一: 创建model模块和加载数据集
  • MySQL 函数
  • Java后端八股------消息中间件篇
  • 微信小程序云开发教程——墨刀原型工具入门(素材面板)
  • 记录一个编译的LLVM 含clang 和 PTX 来支持 HIPIFY 的构建配置
  • Java的控制流语句详解
  • 网络通信另个角度的认识(进程间通信),端口号(为什么要有,和pid的关系,如何封装,和进程的定位原理+对应关系)客户端如何拿到服务端的port
  • 数据结构奇妙旅程之二叉平衡树进阶---AVL树
  • scrapy的基本使用介绍
  • CUDA入门之统一内存
  • 学习大数据,所需要Java基础(9)
  • @angular/forms 源码解析之双向绑定
  • 【技术性】Search知识
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • Akka系列(七):Actor持久化之Akka persistence
  • EOS是什么
  • FastReport在线报表设计器工作原理
  • java8-模拟hadoop
  • MD5加密原理解析及OC版原理实现
  • nodejs调试方法
  • overflow: hidden IE7无效
  • 番外篇1:在Windows环境下安装JDK
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 利用jquery编写加法运算验证码
  • 用Python写一份独特的元宵节祝福
  • 栈实现走出迷宫(C++)
  • ​力扣解法汇总946-验证栈序列
  • # Maven错误Error executing Maven
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #pragma预处理命令
  • #stm32驱动外设模块总结w5500模块
  • (13)Hive调优——动态分区导致的小文件问题
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (C#)获取字符编码的类
  • (超详细)语音信号处理之特征提取
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (十一)c52学习之旅-动态数码管
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转)fock函数详解
  • ./configure,make,make install的作用
  • .Family_物联网
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .NET中GET与SET的用法