1≤N≤18, n很小,可以考虑暴搜
1≤Ci≤W≤108 很像一个背包问题但w很大
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
ll num[30];
ll a[30];
int ans=0;int n;ll w;
void dfs(int u,int cnt)
{
if(u==n+1)
{
ans=min(ans,cnt);
return;
}
if(cnt>=ans) return;//最优性剪枝
for(int i=1;i<=cnt;i++)
{
if(num[i]+a[u]<=w)
{
num[i]+=a[u];
dfs(u+1,cnt);
num[i]-=a[u];//恢复现场
}
}
num[cnt+1]=a[u];
dfs(u+1,cnt+1);
num[cnt+1]=0;//恢复现场
return ;
}
int main()
{
cin>>n>>w;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
ans=n;
sort(a+1,a+1+n);
reverse(a+1,a+1+n);//优化搜索顺序
dfs(1,0);
cout<<ans<<endl;
}