TopCoder SRM 569 Div1 500 TheJediTest (首次Div1 500!!)

啦啦首次做出Div500 虽然只有250+QAQ 因为还是卡了一会

看到数据范围这么小,首先想到了状压
首先显然我们要让每一层的人都尽量是 K 的倍数
我们自下往上逐层考虑
为了接近 K 的倍数,要么由每一层多出来的人往上走,要么就是上面一层的人补下来
把这两种情况状压一下,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;
}

猜你喜欢

转载自blog.csdn.net/ymzqwq/article/details/81637533