有两辆车,容量都为K,有n(10w)个人被划分成m(2k)组,依次上车,每个人上车花一秒。每一组的人都要上同一辆车,一辆车的等待时间是其停留时间*其载的人数,问最小的两辆车的总等待时间。
是f(i,j)表示前i组,j个人是否可行。w(i)表示第i组的人数。
if f(i,j)==1 then f(i+1,j+w(i+1))=1。
这是个bitset可以做的事情,每次左移以后或上f(i-1)的bitset即可。其实可以滚动数组。
然后每更新一次bitset,求一下其最左侧的1的位置,就是对于第一辆车要载的总人数,然后可以O(1)算出第二辆车的等待时间(因为第二辆车必然要接走最后一个人,由于两辆车其实等价,所以可以默认第二辆车等到最后),然后尝试更新答案。
队友代码:
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <cstring> #include <vector> #include <ctime> #include <bitset> using namespace std; bitset<100001> f; struct nod{ int num; long long last; }t[2100]; int n,m,k,a,i,j; long long ans; bool cmp(nod a,nod b) { return a.last<b.last; } int main() { // freopen("ac.in","r",stdin); // freopen("ac.out","w",stdout); scanf("%d%d%d",&n,&m,&k); for (i=1;i<=n;i++) { scanf("%d",&a); t[a].num++; t[a].last=i; } ans=1000000000000; sort(t+1,t+m+1,cmp); f[0]=1; for (i=1;i<=m;i++) { f=(f|(f<<t[i].num)); for (j=k;j>=0;j--) if (f[j]==1 && n-j<=k) { ans=min(ans,j*t[i].last+(n-j)*t[m].last); break; } } if (ans==1000000000000) printf("-1\n"); else printf("%lld\n",ans); }
时间: 2024-10-03 22:40:37