题目传送门https://vjudge.net/problem/CSES-1653#author=GPT_zh
解题思路
使用状压 DP 的思想来设置 DP 状态。
设 表示当前状态下需要的电梯数量, 表示当前状态下多出的人的重量
转移很简单(详见代码)……
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int a[21];
int f[1<<21];
int sum[1<<21];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
memset(f,0x3f,sizeof f);
f[0]=0;
sum[0]=0;
int t1,t2;
for(int i=1;i<(1<<(n));i++)
{
for(int j=1;j<=n;j++)
{
if(i&(1<<(j-1)))
{
t1=f[i^(1<<(j-1))];
t2=sum[i^(1<<(j-1))];
if(t2+a[j]<=m)//若可以放在一个电梯
t2+=a[j];
else//否则分开两个电梯
{
t1++;
t2=a[j];
}
if(t1<f[i])
{
f[i]=t1;
sum[i]=t2;
}
if(t1==f[i]&&t2<sum[i])
{
f[i]=t1;
sum[i]=t2;
}
}
}
// cout<<i<<" "<<f[i]<<endl;
}
if(sum[(1<<(n))-1])
f[(1<<(n))-1]++;
cout<<f[(1<<(n))-1];
return 0;
}