二分贪心 T

本文介绍了一个用于优化产品装箱过程的算法,旨在减少运输成本。该算法通过计算不同大小的产品如何最优地放入标准尺寸的大箱子中,从而实现最小化所需包裹数量的目标。

题目:

A factory produces products packed in square packets of the same height h and of the sizes 1*1, 2*2, 3*3, 4*4, 5*5, 6*6. These products are always delivered to customers in the square parcels of the same height h as the products have and of the size 6*6. Because of the expenses it is the interest of the factory as well as of the customer to minimize the number of parcels necessary to deliver the ordered products from the factory to the customer. A good program solving the problem of finding the minimal number of parcels necessary to deliver the given products according to an order would save a lot of money. You are asked to make such a program.

Input

The input file consists of several lines specifying orders. Each line specifies one order. Orders are described by six integers separated by one space representing successively the number of packets of individual size from the smallest size 1*1 to the biggest size 6*6. The end of the input file is indicated by the line containing six zeros.

Output

The output file contains one line for each line in the input file. This line contains the minimal number of parcels into which the order from the corresponding line of the input file can be packed. There is no line in the output file corresponding to the last ``null'' line of the input file.

Sample Input

0 0 4 0 0 1 
7 5 1 0 0 0 
0 0 0 0 0 0 

Sample Output

2 
1 
分析:
6*6,5*5,4*4每种这样的箱子占一个大箱子,4个3*3的箱子占一个大箱子,2*2的可以放在跟4*4放在一起,也可以跟3*3的放在一起,1*1的可以放在有空的任意地方
代码:
#include<iostream>
using namespace std;
int main()
{
    int i,as,t,a2,a1,a[7];
    while(1)
    {        as=t=0;
        for(i=1;i<7;as+=a[i],i++)
            cin>>a[i];
        if(as==0)
            break;
        t=a[5]+a[4]+a[6]+(a[3]+3)/4;
        if(a[3]%4)
        a2=(3-a[3]%4)*2+1+a[4]*5;
        else
        a2=a[4]*5;
        if(a[2]>a2)
        t+=(a[2]-a2+8)/9;
        a1=(t-a[6])*36-a[5]*25-a[4]*16-a[3]*9-a[2]*4;
        if(a[1]>a1)
            t+=(a[1]-a1+35)/36;
        cout<<t<<endl;
    }
}

下载前可以先看下教程 https://pan.quark.cn/s/16a53f4bd595 小天才电话手表刷机教程 — 基础篇 我们将为您简单的介绍小天才电话手表新机型的简单刷机以及玩法,如adb工具的使用,magisk的刷入等等。 我们会确保您看完此教程后能够对Android系统有一个最基本的认识,以及能够成功通过magisk root您的手表,并安装您需要的第三方软件。 ADB Android Debug Bridge,简称,在android developer的adb文档中是这么描述它的: 是一种多功能命令行工具,可让您与设备进行通信。 该命令有助于各种设备操作,例如安装和调试应用程序。 提供对 Unix shell 的访问,您可以使用它在设备上运行各种命令。 它是一个客户端-服务器程序。 这听起来有些难以理解,因为您也没有必要去理解它,如果您对本文中的任何关键名词产生疑惑或兴趣,您都可以在搜索引擎中去搜索它,当然,我们会对其进行简单的解释:是一款在命令行中运行的,用于对Android设备进行调试的工具,并拥有比一般用户以及程序更高的权限,所以,我们可以使用它对Android设备进行最基本的调试操作。 而在小天才电话手表上启用它,您只需要这么做: - 打开拨号盘; - 输入; - 点按打开adb调试选项。 其次是电脑上的Android SDK Platform-Tools的安装,此工具是 Android SDK 的组件。 它包括与 Android 平台交互的工具,主要由和构成,如果您接触过Android开发,必然会使用到它,因为它包含在Android Studio等IDE中,当然,您可以独立下载,在下方选择对应的版本即可: - Download SDK Platform...
### 二分贪心算法结合使用的解决方案 在某些复杂问题中,可以将二分算法与贪心算法结合使用,以提高解决问题的效率和准确性。以下是关于如何结合这两种算法的一个示例。 #### 示例:分配任务问题 **问题描述**:有 $N$ 个任务需要分配给 $M$ 个人完成,每个人最多只能完成一个任务。每个任务有一个完成时间 $T_i$。目标是找到一种分配方式,使得所有任务完成的时间总和最小化。 **解决思路**: 1. **二分法的应用**:首先通过二分法确定一个可能的最大完成时间 $X$。假设每个人都不能超过这个最大完成时间 $X$。 2. **贪心法的应用**:对于固定的 $X$,使用贪心算法检查是否可以将所有任务分配给 $M$ 个人,并满足每个人的完成时间不超过 $X$。 **具体步骤**: - 使用二分法确定一个可能的最大完成时间 $X$ 的范围。初始时,设定左边界为任务中最短的完成时间,右边界为所有任务完成时间的总和。 - 对于每一个二分得到的中间值 $mid$,使用贪心算法判断是否可以在最大完成时间为 $mid$ 的条件下完成所有任务。 - 如果可以完成,则尝试更小的 $mid$;否则尝试更大的 $mid$。 #### 示例代码 以下是一个基于上述思路的 C++ 示例代码: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; bool canAssign(vector<int>& tasks, int mid, int m) { int count = 1; // 当前需要的人数 int timeSum = 0; // 当前人的累计时间 for (int i = 0; i < tasks.size(); ++i) { if (timeSum + tasks[i] > mid) { // 超过当前限制 count++; timeSum = tasks[i]; if (count > m) return false; // 需要的人数超过限制 } else { timeSum += tasks[i]; } } return true; } int findMinTime(vector<int>& tasks, int m) { sort(tasks.begin(), tasks.end()); // 排序任务 int left = tasks[0]; // 最小的任务时间 int right = accumulate(tasks.begin(), tasks.end(), 0); // 所有任务时间总和 int result = right; while (left <= right) { int mid = (left + right) / 2; if (canAssign(tasks, mid, m)) { result = mid; right = mid - 1; // 尝试更小的值 } else { left = mid + 1; // 尝试更大的值 } } return result; } int main() { vector<int> tasks = {3, 5, 7, 10}; // 每个任务的完成时间 int m = 2; // 可用的人数 cout << "Minimum total time: " << findMinTime(tasks, m) << endl; return 0; } ``` #### 解释 - 在上述代码中,`canAssign` 函数用于检查是否可以在最大完成时间为 `mid` 的条件下完成所有任务[^1]。 - `findMinTime` 函数通过二分查找确定最小的总完成时间[^2]。 - 主函数中定义了任务列表和可用人数,并输出最小的总完成时间[^3]。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值