蓝桥杯 算法训练 粘木棍
题目描述
- 资源限制
时间限制:1.0s 内存限制:256.0MB
- 问题描述
有N根木棍,需要将其粘贴成M个长木棍,使得最长的和最短的的差距最小。
- 输入格式
第一行两个整数N,M。
一行N个整数,表示木棍的长度。
- 输出格式
一行一个整数,表示最小的差距
- 样例输入
3 2
10 20 40
- 样例输出
10
- 数据规模和约定
N, M<=7
方案1 递归 枚举
#include<iostream>
#include<cmath>
using namespace std;
int n;
int m;
int sticks[7];
int long_sticks[7];
int MIN;
int MAX;
int ans=-1;
void f(int cur, int n, int m, int sticks[], int long_sticks[], int MAX){
if(cur == n){
MIN = 0;
for(int i=0; i<m; i++){
if(long_sticks[i]==0){
return ;
}else{
if(MIN!=0){
MIN = min(MIN, long_sticks[i]);
}else{
MIN = long_sticks[i];
}
}
}
if(ans!=-1){
ans = min(ans, (MAX-MIN));
}else{
ans = (MAX-MIN);
}
return ;
}
for(int i=0; i<m; i++){
long_sticks[i] += sticks[cur];
f(cur+1, n, m, sticks, long_sticks, max(MAX, long_sticks[i]));
long_sticks[i] -= sticks[cur];
}
}
int main(){
cin>>n>>m;
for(int i=0; i<n; i++){
cin >> sticks[i];
}
f(0, n, m, sticks, long_sticks, MAX);
cout<<ans<<endl;
return 0;
}
方案2 递归 合并 (避免了大量不符题意的重复计算)
#include<iostream>
#include<cmath>
using namespace std;
int n;
int m;
int sticks[7];
int MIN;
int MAX;
int ans=-1;
void f(int n, int m, int sticks[]){
if(n == m){
MAX = sticks[0];
MIN = sticks[0];
for(int i=1; i<m; i++){
MIN = min(MIN, sticks[i]);
MAX = max(MAX, sticks[i]);
}
if(ans!=-1){
ans = min(ans, (MAX-MIN));
}else{
ans = (MAX-MIN);
}
return ;
}
for(int i=0; i<n-1; i++){
for(int j=i+1; j<n; j++){
int temp = sticks[i];
sticks[j] += sticks[i];
sticks[i] = sticks[n-1];
f(n-1, m, sticks);
sticks[i] = temp;
sticks[j] -= sticks[i];
}
}
}
int main(){
cin>>n>>m;
for(int i=0; i<n; i++){
cin >> sticks[i];
}
f(n, m, sticks);
cout<<ans<<endl;
return 0;
}