【USACO】Subset Sums(双向搜索 dfs)

给你一组数 1 ~ N,问你能有几种分法,把他们分成2组,2组的和相等。

如果 sum(1 ~ n) 为奇数,直接输出0,负责的话 主要找到 和为 sum / 2的组数 再除以2就是结果

因为N 最大为39 如果单向搜索肯定超时,改成双向的就行了

/*
ID: 18906421
LANG: C++
PROG: subset
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 40;
const int maxd = 1500;
LL num[maxn],sum = 0,cnt = 0;
int n;
LL vis[maxd] = {0};
void dfs1(int pos,int num,int s){
    if(s <= sum)
        vis[s]++;
    else
        return;
    for(int i = pos; i <= num; i++)
        dfs1(i + 1,num,s + i);
    return;
}
void dfs2(int pos,int num,int s){
    if(s <= sum){
        int e = sum - s;
        if(vis[e]) cnt += vis[e];
    }
    else
        return;
    for(int i = pos; i <= num; i++)
        dfs2(i + 1,num,s + i);
    return;
}
int main(){
    freopen("subset.in","r",stdin);
    freopen("subset.out","w",stdout);
    cin >> n;
    for(int i = 1; i <= n; i++){
        num[i] = i;
        sum += i;
    }
    if(sum & 1)
        cout << 0 << endl;
    else{
        sum /= 2;
        dfs1(1,n / 2,0);
        dfs2(n / 2 + 1,n,0);
        cout << cnt / 2 << endl;
    }
    return 0;
}
时间: 2024-08-28 10:33:58

【USACO】Subset Sums(双向搜索 dfs)的相关文章

usaco Subset Sums

题意是将1到N的N个数分为两组,要求这两组数字和相等,问有多少种分法 第一遍暴力超时,后来在网上找了才知道是dp,然后这道题的dp方程和01背包有点像,dp[i][j]=dp[i-1][j]+dp[i-1][j-N]; 方程的意思是在i个数字里选出总和为j的方案数,等于在i-1个数里,选出总和为j的方案数(没有i),加上在i-1个数里选出总和j-i的方案数(再加上后来的i,就等于j). 因为返程和01背包很像,所以也能使用和01背包一样的方法优化空间 /* ID: modengd1 PROG:

poj3187Backward Digit Sums(DFS)

题目链接: huangjing 思路: 这个题目想到dfs很容易,但是纠结在这么像杨辉三角一样计算那些值,这个我看的队友的,简直厉害,用递归计算出杨辉三角顶端的值....具体实现详见代码... 题目: Language: Default Backward Digit Sums Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4285   Accepted: 2474 Description FJ and his cows

洛谷P1466 集合 Subset Sums

洛谷P1466 集合 Subset Sums这题可以看成是背包问题 用空间为 1--n 的物品恰好填充总空间一半的空间 有几种方案 01 背包问题 1.注意因为两个交换一下算同一种方案,所以最终 要 f [ v ] / 2 2.要开 long long 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string&g

Project Euler 106:Special subset sums: meta-testing 特殊的子集和:元检验

Special subset sums: meta-testing Let S(A) represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true: S(B) ≠ S(C); that is, sums of subse

【USACO 2.2】Subset Sums (DP)

N (1 <= N <= 39),问有多少种把1到N划分为两个集合的方法使得两个集合的和相等. 如果总和为奇数,那么就是0种划分方案.否则用dp做. dp[i][j]表示前 i 个数划分到一个集合里,和为j的方法数. dp[i][j]=dp[i-1][j]+dp[i][j-i] n 为 39 时,1 到 39 的和为 780,枚举 j 的时候枚举到 s/2,最后输出dp[n][s/2]/2. http://train.usaco.org/usacoprob2?a=z5hb7MFUmsX&

USACO Section 2.2 Subset Sums

/* ID: lucien23 PROG: subset LANG: C++ */ #include <iostream> #include <fstream> using namespace std; int main() { ifstream infile("subset.in"); ofstream outfile("subset.out"); if(!infile || !outfile) { cout << "

USACO 2.2 Subset Sums 【经典的方案DP+必要的转化】

题目在这里:https://www.luogu.org/problem/show?pid=1466#sub 1.把一个连续正整数集合平分,假设该正整数集合和为s,那么平分后的两个集合和均为s/2,因此我们首先把s是奇数的n排除掉 2.接着,我们发现:平分集合方案数======>用n个数凑s/2的方案数======>DP 3.若用f[i][j]表示用前i 个数凑j 的方案,则 f[i][j]=f[i-1][j]+f[i-1][j-i] (1<=i<=n,0<=j<=s/2

USACO Section2.1 Subset Sums 解题报告 【icedream61】

subset解题报告------------------------------------------------------------------------------------------------------------------------------------------------[题目] 把1~N分成两组,让他们的和相等,请问这样的分组有多少种? 但顺序可以颠倒,比如{3}.{2,1}和{2,1}.{3}算作一种.[数据范围] 1<=N<=39[输入样例] 7[输出

USACO 2.2 Subset Sums 集合(subset)

http://zhan.renren.com/000915?gid=3602888498063658248&checked=truehttp://zhan.renren.com/000915?gid=3602888498063658247&checked=truehttp://zhan.renren.com/000915?gid=3602888498063658246&checked=truehttp://zhan.renren.com/000915?gid=36028884980