题解:P12928 [POI 2022/2023 R2] 伐木工人 / Drwale
这真只是绿吗。
我们会尽量让最后被砍伐的木材长度最大,我们单独把他取出来,记为
记两个人砍伐剩下的木材时间分别
说了这么多,其实最晚时间就是
但是朴素背包会超时,考虑二进制优化,算了下复杂度是
可以套用容量和价值一样时用的 bitset 来优化,复杂度是
可能有人对为什么二进制优化的背包是复杂度是
但是二进制优化不是还有
代码实现非常简单:
#include<bits/stdc++.h>
// #define int long long
using namespace std;
/*
#pragma region 哈基米
*/
inline int read(){
int x=0,f=1;char c=getchar();
while(c>'9'||c<'0') {if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
const int N=1e6+5,V=5e6+5;
int n,mx,ans,tot,a[N],t[V];bitset<V> s;
signed main(){
// freopen("1.in" ,"r",stdin );
n=read();s[0]=1;
for(int i=1;i<=n;i++) t[a[i]=read()]++,mx=max(mx,a[i]);
t[mx]--;
for(int i=1;i<V;i++) if(t[i]) {
tot+=t[i]*i;
for(int k=1;k<=t[i];k<<=1) t[i]-=k,s|=s<<(i*k);
if(t[i]) s|=s<<(i*t[i]);
}
for(int i=0;i<V;i++) if(s[i]) ans=max(ans,min(i,tot-i)+mx);
printf("%d\n",ans);
return 0;
}