题目链接:小猫爬山
解法一:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 20;
int n,m;
int cat[N],sum[N];
int ans=N;
void dfs(int now,int cnt) {
if(cnt>=ans) return ; //剪枝
if(now == n+1) {
ans = min(ans,cnt);
return ;
}
//枚举当前所有车
for(int i=1; i<=cnt; i++) {
if(cat[now] + sum[i] <= m) {
sum[i]+=cat[now];
dfs(now+1,cnt);
sum[i]-=cat[now];//还原
}
}
sum[cnt+1]=cat[now];//把猫放入新车
dfs(now+1,cnt+1);
sum[cnt+1]=0;//回溯
}
int main() {
cin >> n >>m;
for(int i=1; i<=n; i++) cin>>cat[i];
sort(cat+1,cat+n+1);
reverse(cat+1,cat+n+1);
dfs(1,0);
cout<<ans<<endl;
return 0;
}
解法二:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 20;
int n,m;
int cat[N],sum[N];
int ans=N;
void dfs(int u,int k) {
if(k>=ans) return ;
if(u == n) {
ans = k;
return ;
}
for(int i=0; i<k; i++) {
if(sum[i]+cat[u]<=m) {
sum[i]+=cat[u];
dfs(u+1,k);
sum[i]-=cat[u];
}
}
sum[k]=cat[u];
dfs(u+1,k+1);
sum[k]=0;
}
int main() {
cin >> n >>m;
for(int i=0; i<n; i++) cin>>cat[i];
sort(cat,cat+n);
reverse(cat,cat+n);
dfs(0,0);
cout<<ans<<endl;
return 0;
}