【DP】【bitset】17.6.4 均分 题解
2017-06-05 20:57
141 查看
暴力就是做背包,然后找最接近一半的可以凑出来的值
由n<=10^6且sigma a[i]<=10^6我们可以知道不相等的a[i]最多有根号10^6种
那么就从一个10^6个物品的背包变成了10^3个物品的每个物品可以有多个的背包
用二进制拆包优化,复杂度为10^3*10^6*log
用bitset优化,再除以32
事实上可以参考2015年任之洲集训队论文,提出了一种n log n的近似算法,效果也很优秀,审题人并未实现,不过应该可以AC,因为曾经用这个算法AC过其他的带权均分问题
#include<iostream> #include<cstdio> #include<cstdlib> #include<bitset> #include<cstring> #include<string> #include<cmath> #include<algorithm> #define INF_min 1e9 using namespace std; int T,n,tot,ans; int a[1000001],cnt[1001]; bitset <1000005> bit; int main() { freopen("share.in","r",stdin); freopen("share.out","w",stdout); scanf("%d",&T); while(T--) { bit.reset();tot=0; memset(cnt,0,sizeof(cnt)); scanf("%d",&n); bit[0]=1; for(int i=1;i<=n;i++){scanf("%d",&a[i]);tot+=a[i];} for(int i=1;i<=n;i++) { if(a[i]<sqrt(tot))cnt[a[i]]++; else bit|=bit<<a[i]; } int t=1; for(int i=1;i<=sqrt(tot);i++) { t=1; while(cnt[i]) { if(cnt[i]>=t) { bit|=bit<<(i*t); cnt[i]-=t; t*=2; } else {bit|=bit<<(cnt[i]*t);cnt[i]=0;} } } ans = INF_min; for(int i=0;i<=bit.size();i++) if(bit[i]) ans = min(ans, abs(i-(tot-i))); printf("%d\n",ans); } return 0; }
相关文章推荐
- hdu5313Bipartite Graph(二分图染色+DP(bitset优化))
- hdu5890 bitset 优化dp
- HDU 5745 La Vie en rose(bitset优化dp)
- HDU 5745 dp, bitset优化
- HDOJ 5745 La Vie en rose DP+bitset
- 牛客练习赛22-C-dp+bitset
- HDU 5745 La Vie en rose bitset优化dp
- UVa 10651 Pebble Solitaire (DP&bitset)
- 2015 Multi-University Training Contest 10 (hdu 5406-5416)数据结构+dp+矩阵快速幂+bitset优化拓扑排序+(dp&树状数组)
- 洛谷Oj-P1441 砝码称重-深搜+DP/Bitset
- 【2015-2016 XVI Open CupJ】【DP bitset记录方案】Judgement n人投票前后权威值改变是否有实际区别
- HDU 5616 Jam's balance dp, bitset
- hdu5890 bitset优化DP
- LibreOJ 515 贪心只能过样例(dp[bitset优化])
- zjnu1709 UZASTOPNI (bitset,树形dp)
- codeforces 788C The Great Mixing( BFS / dp+bitset优化 )
- BZOJ 3687 简单题【dp,bitset基础应用
- BZOJ 2208 [Jsoi2010]连通数 tarjan缩点+bitset优化DP
- bzoj3687 -- bitset优化DP
- 【bzoj3687】简单题 背包dp+STL-bitset