啦啦首次做出Div500 虽然只有250+QAQ 因为还是卡了一会
看到数据范围这么小,首先想到了状压
首先显然我们要让每一层的人都尽量是
的倍数
我们自下往上逐层考虑
为了接近
的倍数,要么由每一层多出来的人往上走,要么就是上面一层的人补下来
把这两种情况状压一下,1表示往上走,0表示走下来
有一个需要注意的地方就是一个人只能走一层,所以移动人数还要和原来人数取min
#include <bits/stdc++.h>
using namespace std;
const int N=21;
int n,c[N];
class TheJediTest {
public:
int minimumSupervisors( vector <int> students, int K );
};
int divv(int n,int k){
return n%k?n/k+1:n/k;
}
int TheJediTest::minimumSupervisors(vector <int> a, int K) {
n=a.size();
int ans=2e9;
for(int o=0;o<1<<(n-1);o++){
int s=0;
for(int i=0;i<n;i++) c[i]=a[i];
for(int i=0;i<n-1;i++){
int d=c[i]%K;
//if (d==0) d=K;
if (o&(1<<i)){
int v=min(a[i],d);
c[i]-=v;
c[i+1]+=v;
} else{
d=K-d;
if (d==K) d=0;
int v=min(a[i+1],d);
c[i]+=v;
c[i+1]-=v;
}
s+=divv(c[i],K);
}
s+=divv(c[n-1],K);
ans=min(ans,s);
}
return ans;
}