dfs
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,c[19],v[19];
bool dfs(int x,int num)//num为车厢号
{
for(int i=1;i<=x&&i<=num;i++)
{
if(v[i]+c[x]<=m)
{
v[i]+=c[x];
if(x==n)
return 1;
if( dfs(x+1,num) )
return 1;
v[i]-=c[x];
}
}
return false;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>c[i];
for(int i=1;i<=n;i++)
{
fill(v+1,v+1+n,0);
if(dfs(1,i))
{
cout<<i<<endl;
break;
}
}
return 0;
}
dp
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,w;
int a[20];
int f[1<<18];//f[i]状态为i的最小次数
int g[1<<18];//g[i]状态为i时,最后一个电梯的剩余体积
int main() {
cin>>n>>w;
for(int i=0; i<n; i++)
cin>>a[i];
fill(f,f+(1<<18)+1,1e9+10);
f[0]=1;
g[0]=w;
for(int i=0; i< (1<<n); i++ ) { //枚举状态
for(int j=0; j<n; j++) {
if(i&(1<<j))
continue;
if(g[i]>=a[j]&&f[i|(1<<j)]>=f[i]) {
f[i|(1<<j)]=f[i];
g[i|(1<<j)]=max(g[i|(1<<(j))],g[i]-a[j]);
} else if(g[i]<a[j] || f[i|(1<<(j))]>=f[i]+1) {
f[i|(1<<(j))]=f[i]+1;//电梯次数+1
g[i|(1<<(j))]=max(g[i|(1<<(j))],w-a[j]);
}
}
}
printf("%d",f[(1<<n)-1]);
return 0;
}