[usaco]2.2 Subset Sums
来源:互联网 发布:知乎 希拉里 维基 编辑:程序博客网 时间:2024/05/18 00:24
大概的题意是: 给定一个序列 1 。。N ,假设全集为U那么存在多少种情况 : 两个子集A B其中A∩B=∅ ,A∪B=U, A元素的和== B元素的和。开始写了个递归,枚举,提交超时:
原始博客地址: http://www.fuxiang90.com/2012/07/usaco2-2-subset-sums/
void work(int deep,int start){ if(deep >= n) return; if(ans > (sum -ans)) return ; if(ans == sum-ans) { gcount ++; /*FOR_1(i,1,n){ if(used[i] == 1) fout<<i<< " "; } fout<<endl;*/ return ; } FOR_1(i,start + 1,n){ if(used[i] == 0){ used[i] = 1; ans += i; work(deep + 1,i); used[i] = 0; ans -= i; } } }
之后改用另外一种思路,f(n,ans) = f(n-1,ans-n) + f(n-1,ans) ,这个有点分治的思路,把问题的规模逐渐缩小,从而得到解。中间加了个优化,用一个二维数组存下中间计算的结果,这样就不会超时。
/*ID:fuxiang2PROG: subsetLANG: C++*/#include <iostream>#include <fstream>#include <stack>#include <string>#include <vector>#include <queue>#include <map>#include <list>#include <algorithm>#include <set>#include <cmath>#include <cstring>#include <cstdlib> #define REP(i, n) for (int i=0;i<int(n);++i)#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)#define REP_1(i, n) for (int i=1;i<=int(n);++i)#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)#define EACH(it, A) for (typeof(A.begin()) it=A.begin(); it != A.end(); ++it) using namespace std;ofstream fout ("subset.out");ifstream fin ("subset.in"); const int N = 40;int used[N];int n ;int sum;int ans ;int gcount ;int data[40][800];void work(int deep,int start){ if(deep >= n) return; if(ans > (sum -ans)) return ; if(ans == sum-ans) { gcount ++; /*FOR_1(i,1,n){ if(used[i] == 1) fout<<i<< " "; } fout<<endl;*/ return ; } FOR_1(i,start + 1,n){ if(used[i] == 0){ used[i] = 1; ans += i; work(deep + 1,i); used[i] = 0; ans -= i; } } } int solve(int n ,int ans){ int msum = (n+1)*n/2; if(ans <= 0) return 0; if(msum < ans) return 0 ; else if(msum == ans ) return 1 ; if(data[n][ans] ) return data[n][ans] ; data[n-1][ans-n] = solve(n-1,ans-n); data[n-1][ans] = solve(n-1,ans); return data[n-1][ans-n] + data[n-1][ans];}int main(){ fin>>n; sum = (1+n)*n/2; ans = 0; if(sum%2 ==1){ fout<<"0"<<endl; } else { //work(0,0); //fout<<gcount/2 <<endl; int re = solve(n,sum/2); fout<<re<<endl; } //int re = solve(n,sum/2); //fout<<re<<endl; return 0; }
原始博客地址: http://www.fuxiang90.com/2012/07/usaco2-2-subset-sums/
- USACO 2.2 Subset Sums (subset)
- USACO 2.2 Subset Sums
- [usaco]2.2 Subset Sums
- USACO 2.2 Subset Sums
- USACO 2.2 Subset Sums
- USACO 2.2:Subset Sums
- [USACO 2.2.2] Subset Sums
- USACO 2.2.2 Subset Sums
- USACO Section 2.2 Subset Sums
- usaco 2.2.2 subset sums
- USACO 2.2.2 Subset Sums
- USACO Section 2.2 Subset Sums
- usaco 2.2.2 Subset sums
- USACO 2.2 集合 Subset Sums
- USACO 2.2.2 Subset Sums
- USACO section 2.2 Subset Sums(DP,背包)
- DP USACO 2.2.2 Subset Sums 集合
- USACO:2.2.2 Subset Sums 集合和
- SDN & OpenFlow 3
- working with IE
- 美国男子成世界首例被确认治愈的艾滋病患者
- 片段 - Fragments
- android ListView用法
- [usaco]2.2 Subset Sums
- Java WEB XML 简介
- 做完小东西
- android手机返回键对应处理
- 查看vmlinux的符号信息
- SDN & OpenFlow 4
- Hypertable - 安装-MapR
- Android中实现滑动翻页—使用ViewFlipper
- 加载器 - Loaders