https://ac.nowcoder.com/acm/contest/882/F

潘哥的代码才卡过去了,自己写的都卡不过去,估计跟评测机有关。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int maxn=30;
  5. int g[maxn][maxn],n;
  6. ll ans;
  7. inline void dfs(int mask,int last,int dep,ll sum)
  8. {
  9. if(!dep){
  10. if(sum>ans) ans=sum;
  11. return;
  12. }
  13. if(n-last-1<dep) return;
  14. for(int i=last+1;i<n;++i){
  15. ll tmp=sum;
  16. for(int j=0;j<n;++j){
  17. if(mask>>j&1) tmp-=g[i][j];
  18. else tmp+=g[i][j];
  19. }
  20. dfs(mask|(1<<i),i,dep-1,tmp);
  21. }
  22. return;
  23. }
  24. int main()
  25. {
  26. #ifdef local
  27. freopen("a.txt","r",stdin);
  28. #endif // local
  29. scanf("%d",&n);
  30. n<<=1;
  31. for(int i=0;i<n;++i){
  32. for(int j=0;j<n;++j){
  33. scanf("%d",&g[i][j]);
  34. }
  35. }
  36. ll sum=0;
  37. for(int i=1;i<n;++i) sum+=g[0][i];
  38. dfs(1,0,n/2-1,sum);
  39. printf("%lld\n",ans);
  40. return 0;
  41. }

应该最卡常的思路是折一半,2^14预处理前半部分内部的贡献,再一次预处理后半部分内部的贡献。

答案当然就是,前半部分选了i个1,后半部分选n-i个1的,那么考虑他们合并在一起的新的影响。

暴力的话当然是前半部分的每个1对后半部分的每个0匹配一次。然后后半部分的每个1对前半部分的0匹配一次。

复杂度的话,每种组合实际上都要遍历到,\(C_{2n}^n\) 少不了了。但是每次合并只和1的数量有关。所以需要预处理的时候把“前半部分的该状态的0对后半部分的某个1的贡献”也搞出来。

理论上比这个搜索快多的。这个是咖啡鸡的代码的注释版:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. ll s[1 << 14], t[1 << 14], p[14], q[14], ret, ans;
  5. int c[30][30], n, d[1 << 14];
  6. //枚举t状态
  7. void dfs(int step, int w, int mask, ll sum) {
  8. //对后半部分搜索完毕
  9. if(step == n) {
  10. ret = max(ret, sum + t[mask]);
  11. return;
  12. }
  13. //选择的人没满,后半部分可以再选一个
  14. if(w < n)
  15. //这一次step选1,也就是后半部分的第step位选1,后半部分第step个选1那当然要加step
  16. dfs(step + 1, w + 1, mask | (1 << step), sum + p[step]);
  17. //等价于n-step+w>n,也就是剩下的人+已选的人超过需要选的人,那么这一步可以选0
  18. if(w > step)
  19. dfs(step + 1, w, mask, sum + q[step]);
  20. }
  21. int main() {
  22. #ifdef Yinku
  23. freopen("Yinku.in", "r", stdin);
  24. #endif // Yinku
  25. scanf("%d", &n);
  26. //d[i]表示i状态有多少个1,用于连接两个集合使用
  27. d[0] = 0;
  28. for(int i = 1; i < (1 << n); i++)
  29. d[i] = d[i / 2] + i % 2;
  30. for(int i = 0; i < n * 2; i++)
  31. for(int j = 0; j < n * 2; j++)
  32. scanf("%d", &c[i][j]);
  33. //折半枚举
  34. //s[i]表示前半部分内部的贡献,t[i]表示后半部分内部的贡献
  35. for(int i = 0; i < (1 << n); i++) {
  36. for(int j = 0; j < n; j++)
  37. if(!(i & (1 << j)))
  38. for(int k = j + 1; k < n; k++)
  39. if(i & (1 << k))
  40. s[i] += c[j][k], t[i] += c[j + n][k + n];
  41. for(int j = 0; j < n; j++)
  42. if(i & (1 << j))
  43. for(int k = j + 1; k < n; k++)
  44. if(!(i & (1 << k)))
  45. s[i] += c[j][k], t[i] += c[j + n][k + n];
  46. }
  47. //折半枚举
  48. //p[k]表示当前前半部分为i状态,后半部分的第k个为1的时候的对前半部分的所有的0产生的贡献
  49. //q[k]表示当前前半部分为i状态,后半部分的第k个为0的时候的对前半部分的所有的1产生的贡献
  50. for(int i = 0; i < (1 << n); i++) {
  51. for(int k = 0; k < n; k++)
  52. p[k] = 0, q[k] = 0;
  53. for(int j = 0; j < n; j++) {
  54. if(!(i & (1 << j)))
  55. for(int k = 0; k < n; k++)
  56. p[k] += c[j][k + n];
  57. else
  58. for(int k = 0; k < n; k++)
  59. q[k] += c[j][k + n];
  60. }
  61. ret = 0;
  62. //前半部分为i状态,它拥有d[i]个已选择的人
  63. dfs(0, d[i], 0, 0);
  64. //把前半部分的s[i]状态加进去
  65. ans = max(ans, ret + s[i]);
  66. }
  67. printf("%lld\n", ans);
  68. }

2019牛客暑期多校训练营(第二场) - F - Partition problem - 枚举的更多相关文章

  1. 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)

    题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...

  2. 2019 牛客暑期多校 第三场 F Planting Trees (单调队列+尺取)

    题目:https://ac.nowcoder.com/acm/contest/883/F 题意:求一个矩阵最大面积,这个矩阵的要求是矩阵内最小值与最大值差值<=m 思路:首先我们仔细观察范围,我 ...

  3. 2020牛客暑期多校训练营 第二场 K Keyboard Free 积分 期望 数学

    LINK:Keyboard Free 我要是会正经的做法 就有鬼了. 我的数学水平没那么高. 三个同心圆 三个动点 求围成三角形面积的期望. 不会告辞. 其实可以\(n^2\)枚举角度然后算出面积 近 ...

  4. 2020牛客暑期多校训练营 第二场 J Just Shuffle 置换 群论

    LINK:Just Shuffle 比较怂群论 因为没怎么学过 置换也是刚理解. 这道题是 已知一个置换\(A\)求一个置换P 两个置换的关键为\(P^k=A\) 且k是一个大质数. 做法是李指导教我 ...

  5. 2020牛客暑期多校训练营 第二场 I Interval 最大流 最小割 平面图对偶图转最短路

    LINK:Interval 赛时连题目都没看. 观察n的范围不大不小 而且建图明显 考虑跑最大流最小割. 图有点稠密dinic不太行. 一个常见的trick就是对偶图转最短路. 建图有点复杂 不过建完 ...

  6. 2020牛客暑期多校训练营 第二场 C Cover the Tree 构造 贪心

    LINK:Cover the Tree 最受挫的是这道题,以为很简单 当时什么都想不清楚. 先胡了一个树的直径乱搞的贪心 一直过不去.后来意识到这类似于最经典长链剖分优化贪心的做法 然后那个是求最大值 ...

  7. 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心

    LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...

  8. 2020牛客暑期多校训练营 第二场 A All with Pairs 字符串hash KMP

    LINK:All with Pairs 那天下午打这个东西的时候状态极差 推这个东西都推了1个多小时 (比赛是中午考试的我很困 没睡觉直接开肝果然不爽 一开始看错匹配的位置了 以为是\(1-l\)和\ ...

  9. 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem

    题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3  4 2 3 4 输出:0 0 1 题解: 认真想一 ...

  10. 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题)

    layout: post title: 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题) author: "luowentaoaa" c ...

随机推荐

  1. css文档之盒模型阅读笔记

    前段时间抽空仔细阅读了w3c的css文档关于盒模型方面的一些基础知识.边读边记录了一些要点,在此做些整理,与大家分享,如有理解有误之处,请不吝指教. 1.综述 文档中的每个元素被描绘为矩形盒子.渲染引 ...

  2. 2018-2-13-win10-uwp-smms图床

    title author date CreateTime categories win10 uwp smms图床 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 1 ...

  3. 13DBUtils工具类

    如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils. DBUtils就是JDBC的简化开发工具包.需要项 ...

  4. [NOI1999]生日蛋糕(搜索)

    [NOI1999]生日蛋糕 题目背景 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层 生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1<=i<=M)层蛋糕是半 ...

  5. [python 学习] requests 库的使用

    1.get请求 # -*- coding: utf-8 -*- import requests URL_IP = "http://b.com/index.php" pyload = ...

  6. 理解Promise (2)

    一进来 我们开始执行 executor函数 传递两个参数 再调用 then 方法 ,then 方法里面有 OnResolve方法,OnReject 方法  在then 方法中,我们一开始的状态是pen ...

  7. css3 :enabled与:disabled伪类选择器

    css :enabled和:disabled伪类选择器 在Web表单中,有些表单元素(如输入框.密码框.复选框等)有“可用”和“不可用”这2种状态.默认情况下,这些表单元素都处在可用状态. 在CSS3 ...

  8. JAVA四种引用方式

    JAVA四种引用方式: java.lang.ref: 强引用(直接变量赋值) 软引用(SoftReference): 只有在要发生OOM错误之前才会回收掉老的软引用对象,应用场景主要防止内存溢出.(缓 ...

  9. 重置Jenkins的构建历史

    1.重置单个JOB的构建历史item = Jenkins.instance.getItemByFullName("your-job-name-here") //THIS WILL ...

  10. discuz x3.2设置注册邮件激活_企业邮箱发送邮件失败

    在discuz x2.5邮箱设置里面已经说了很多关于邮件设置和常见问题的处理办法了,今天这里主要是说明下Discuz! 邮件发送失败排查思路,适用于任何板块的Discuz程序. Discuz! 邮件发 ...