CF1303D Fill The Bag 题解
jiangtaizhe001 · · 题解
可能更好的阅读体验
题目传送门
题目大意
给定一个大小为
题目解析
不难想到二进制拆分。考虑贪心。
二进制拆分后,如果这一位没有大小恰好为
如果从高到低考虑,我们不难发现这是假的,所以考虑从低到高位考虑。
具体的做法是这样的:
从低位到高位考虑,如果这一位恰好有大小为
现在来证明这种做法的正确性和时间复杂度。
先证明正确性。不难发现如果将一个大小为
然后证明时间复杂度。如果我们将分割了一个大小为
无解的情况是显然的,因为切割的时候总体积不变,所以只要
核心代码:
int n,x,ans,t[39]; ll m,sum;
void work(){
m=read(); n=read(); Me(t,0); sum=0; ans=0; int i,j;
for(i=1;i<=n;i++) x=read(),sum+=x,t[(int)log2(x)]++;
if(sum<m){ puts("-1"); return; } if(sum==m){ puts("0"); return; }
for(i=0;i<31;i++){
if(!t[i]&&(m&(1<<i))){ j=i; while(!t[j]) j++,ans++; t[j]--; for(j=j-1;j>=i;j--) t[j]++; }
if(m&(1<<i)) t[i]--; t[i+1]+=(t[i]>>1);
} print(ans),pc('\n'); return;
}