题目重述
木匠在制作家具前往往需要将木料分割成长度不同的木块,在每次分割时都会损坏一定长度的木头。现需制作一件家具,已知每块木料的长度, 该家具制作时所需的木块的长度以及分割时损坏的木块的长度,请编写程序计算制作这些家具最少需要多少块木料。
输入要求:输入1行,包含若干个整数,第1个整数是木料的长度,第2个整数为每次分割损坏的木块的长度,后面的整数则为该家具制作时所需的木块的长度。
输入要求:输出1个整数,即制作该家具所需的木料的块数。
样例输入:
1000 100 250 250 500 650 1000
样例输出:
3
分析:
如果分割后的木块长度不符合题目要求的长度,该木块也不能使用,不能将各次分割后不符合要求的木块拼接所以,所以如上图,求木料的切割可以理解为搜索切割木料的排列方式,从中选出一种消耗木板最小的切割顺序。对于切割损失的处理为,每块切割实际损耗木料为分割损坏的木块的长度与所需的木块的长度之和,而最后一次切割将不损耗木料,块的长度与所需的木块的长度之和,而最后一次切割将不损耗木料,于是计算时将木料长度设计为木料长度与一次切割损耗之和。
于是计算时将木料长度设计为木料长度与一次切割损耗之和。
算法的文字描述
Step1:输入整形变量木料的长度和每次分割损坏的木块的长度,字符串型的家具制作时所需的木块的长度。
Step2 将输入的所需木块长度的字符串转化存储在整形数组中。
Step3:修改木料的长度为木料的长度与每次分割损坏的木块的长度之和,所需木块长度为所需木块长度与每次分割损坏的木块的长度之和。
Step4:对整形数组所需木块长度做全排列枚举,并计算每种切割的排列方式需要的木料块数,记录最小的排列方式。
Step5:输出最少需要多少块木料。
算法的源代码
#include<iostream>
#include<sstream>
using namespace std;
void s2i(string str, int &demand) {
stringstream ss;
ss << str;
ss >> demand;
}
void Swap(int& i, int& j)
{
int temp;
temp = i;
i = j;
j = temp;
return;
}
/********记录用料最少的块数及其排列方式********/
int min_log(int *list,int length,int m) {
int num = 1,sum=0;
for (int i = 1; i <= m; i++) {
sum += list[i];
if (sum > length) {
sum -= list[i];
num++;
sum= list[i];
}
}
return num;
}
/********搜索树的排列********/
//传递需求常数,起点,深度,木料长度,引用最小排列,最小块数
void Perm(int* list, int k, int m, int length,int *min_list,int &min)
{
int i;
if (k == m) {//到叶子节点
int t = min_log(list, length, m);
if (min > t)
{
min = t;
memcpy(min_list, list, sizeof(int) * 20);
}
}
else {
for (i = k; i <= m; i++) {//向右
Swap(list[k], list[i]);
Perm(list, k + 1, m,length, min_list,min);//向下
Swap(list[k], list[i]);
}
}
return ;
}
void main() {
int log_length = 0, cut_cost = 0;
int demand[100] = { 0,0,}, min_list[100] = { 0,0, };
int k=0,min_log=INT_MAX;
cin >> log_length >> cut_cost;
/******************/
string s;
getline(cin, s);
istringstream iss(s);
string tmp;
while (getline(iss,tmp,' '))
{
s2i(tmp, demand[k++]);
}
k--;
//此时demand[0]=0
/******************/
log_length= log_length+ cut_cost;
for (int i = 1; i <= k; i++) {
demand[i]= demand[i]+ cut_cost;
}
/*********搜索*********/
Perm(demand, 1, k,log_length,min_list, min_log);
cout << min_log<<endl;
}