首页 > 其他分享 >洛谷 P3067 [USACO12OPEN]Balanced Cow Subsets G 折半搜索

洛谷 P3067 [USACO12OPEN]Balanced Cow Subsets G 折半搜索

时间:2022-10-10 17:57:01浏览次数:91  
标签:折半 洛谷 P3067 int sum include border id

题目

https://www.luogu.com.cn/problem/P3067

思路

考虑折半搜索,第一个dfs对[1,n/2]的数进行分组,+代表第一组,-代表第二组,并计算两组总和的情况方案数\(a_i\)。

第二个dfs对[n/2+1,n]的数统计数字和为sum的方案\(b_i\),同时与前n/2个数的方案进行匹配,寻找\(a_i\)中和为-sum的方案。两者和为1代表一种结果。

分组的去重方法:

考虑状态压缩,给每一个数分配一个二进制位(1代表选择,0代表不选),那么对应的每一种方案数获得一种二进制编号。

将\(a_i\)和\(b_i\)对应的二进制编号拼在一起,并判断重复即可。

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<unordered_map>

const int maxm = (1 << 20) + 10;
const int maxn = 30 + 5;
std::unordered_map<long long, std::vector<int> > mp;
int num[maxn];
int n;
long long ans;
bool vis[maxm];

void dfs1(int x, int sum, int border, int id) {
    if (x > border) {
        mp[sum].push_back(id);
        return;
    }
    dfs1(x + 1, sum + num[x], border, (id << 1) | 1);//左侧
    dfs1(x + 1, sum - num[x], border, (id << 1) | 1);//右侧
    dfs1(x + 1, sum, border, id << 1);//不选
}

void dfs2(int x, int sum, int border, int id) {
    if (x > border) {
        for (int i: mp[-sum]) {
            if (vis[(i << 10) | id]) continue;//去重
            vis[(i << 10) | id] = 1;
            ans++;
        }
        return;
    }
    dfs2(x + 1, sum + num[x], border, (id << 1) | 1);//左侧
    dfs2(x + 1, sum - num[x], border, (id << 1) | 1);//右侧
    dfs2(x + 1, sum, border, id << 1);//不选
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &num[i]);
    }
    dfs1(1, 0, n / 2, 0);
    dfs2(n / 2 + 1, 0, n, 0);
    std::cout << ans - 1;
}

标签:折半,洛谷,P3067,int,sum,include,border,id
From: https://www.cnblogs.com/MrWangnacl/p/16776632.html

相关文章

  • 洛谷 P3530 / bzoj2788【tarjan】【差分约束】
    判断是否有解可以使用差分约束。求解赛车手的成绩的取值可以使用Floyd。但是\(O(n^3)\)会TLE。可以先进行一次缩点。然后进行Floyd求出每一个连通块内的最长路径......
  • DS | 折半查找二叉判定树的画法
    以下给出我在学习中总结的一种比较简便的构造折半二叉判定树的思路以及方法:思路分析:在计算\(mid\)值时,使用的时\(mid=(low+high)/2\)。这里由于\(mid\)为int类......
  • 洛谷 P5194 [USACO05DEC]Scales S 折半搜索
    题目https://www.luogu.com.cn/problem/P5194思路\(n\leq1000\)的范围很吓人,但是按照【每个砝码的质量至少等于前面两个砝码的质量的和】的规则,打表可知n在50时总重量......
  • 【做题笔记】洛谷P5584 【SWTR-01】Sunny's Crystals
    ProblemP5584【SWTR-01】Sunny'sCrystals题目大意:给你一个长度为\(n\)的序列,每次可以删掉下标为\(2\)的非负整数次幂的数,删掉一个数后他后面的数会往前补,问删掉所......
  • 洛谷 P6146
    由于博主是只鸽子,所以咕咕咕。()不,应该是目录不在更新,请关注博客首页。有空我把目录更新一下,好久不更了传送门YouareMiserable(ATLv.15)思路Stage1这题其实是个......
  • Solution -「CSTC 2017」「洛谷 P3772」游戏
    \(\mathscr{Description}\)  有\(n\)个随机真值\(x_{1..n}\),已知\(P(x_1=1)=p_1\),对于\(2\lei\len\),\(P(x_i=1\midx_{i-1}=1)=p_i\),\(P(x_i=1\midx_{i......
  • 洛谷 P2387 [NOI2014] 魔法森林 题解【动态加点 SPFA】
    题目大意给定一个由\(n\)个点\(m\)条边的无向图,每条边有权值\((a,b)\),求一条路径使这条路径上的\((a_{\max}+b_{\max})\)最小。思路正解应该是LCT动态维护MST......
  • Solution -「SDOI 2017」「洛谷 P3706」硬币游戏
    \(\mathscr{Description}\)  Link.  给定\(n\)个长度为\(m\)且两两不同的字符串\(S_{1..n}\),字符集\(|\Sigma|=2\).各位置独立在\(\Sigma\)中均匀随机,......
  • P5730 【深基5.例10】显示屏 洛谷
    #include<stdio.h>intmain(){charstr1[30]="XXX..XXXXXXXX.XXXXXXXXXXXXXXXX";charstr2[30]="X.X..X..X..XX.XX..X....XX.XX.X";charstr3[30]="X.......
  • 网络流24题 -洛谷 P2762 太空飞行计划问题
    P2762太空飞行计划问题题意给你n个实验m个仪器(原题中n和m反了一下)第i个实验会给一个赞助费\(c[i]\)每个实验都有相应的实验仪器买第m个实验器材要\(c_2[i]\)的钱问......