USACO 2.2 Subset Sums 集合(subset)
2015-04-04 15:47
323 查看
Description
对于从1到N的连续整集合,能划分成两个子集合,且保证每个集合的数字和是相等的。举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,他们每个的所有数字和是相等的:
{3} and {1,2}
这是唯一一种分法(交换集合位置被认为是同一种划分方案,因此不会增加划分方案总数)
如果N=7,有四种方法能划分集合{1,2,3,4,5,6,7},每一种分发的子集合各数字和是相等的:
{1,6,7} and {2,3,4,5} {注 1+6+7=2+3+4+5}
{2,5,7} and {1,3,4,6}
{3,4,7} and {1,2,5,6}
{1,2,4,7} and {3,5,6}
给出N,你的程序应该输出划分方案总数,如果不存在这样的划分方案,则输出0。程序不能预存结果直接输出。
好 废话不多说这是我在Ubuntu下打的第一个代码,个人认为Ubuntu下很多界面较好 风格也还行(又说废话了)。。。
这道题是一个dp 大致的意思是从1-n的每个数都给你一个 然后叫你找有多少种可能a+b+c...==x+y+z(当然a,b,c,x,y,都属于这n个数)同时 这些数都要用完而且不能重复用
刚刚看题目颇为不解 这用dp该怎么做 明显是坑爹嘛 后来实在想不出来就去baidu了(。。。) 然后看到一种普遍的解法就是看作一个01背包然后“
如果M=n*(n+1)/2是奇数,则没有分法。如果是偶数,背包容量为M/2,dp[k] += dp[k-i],(i=1,2,...,n)计算k的时候为避免重算,
需倒着进行。”(这不还是看不懂嘛(请原谅我的愚笨))
再后来一想[1,n]这个区间里所有数不久形成了一个an=n的等差数列嘛 那么根据求和公式sn=n+n*(n-1)/2 =n*(n+1)/2 既然这样 要使两边相等 那么
l(左边的和)=r(右边的和)=n*(n+1)/4 这样的话如果算出来的n*(n+1)/4为小数的话那么肯定就不可能有解了嘛 所以只要在开始判断一下n*(n+1)/4能不能除尽(即判断n*(n+1)%4是否为0) 然后如果除不尽就直接return 掉就行了。
在初步的判断完以后 我们就要开始用dp大法了 可以看作有n个物品 给你n*(n+1)/4的质量 这一次的分法就等于这一次j比i多出来的数的分法加上原来i的分法
代码如下:
#include<iostream> using namespace std; const int maxn=10000+10; long long f[100000]; int n,s; int main() { cin>>n; s=n*(n+1); if(s%4!=0) { cout<<0<<endl; return 0; } s/=4; f[0]=1; for(int i=1;i<=n;i++) for(int j=s;j>=i;j--) f[j]+=f[j-i]; cout<<f[s]/2<<endl; return 0; }
相关文章推荐
- [USACO2.2]集合 Subset Sums
- USACO-Section2.2 Subset Sums【动态规划】
- 【USACO 2.2】Subset Sums (DP)
- USACO-Section 2.2 Subset Sums (DP)
- USACO 2.2 Subset Sums (DP动态规划)
- USACO 2.2 Subset Sums(水DP)
- USACO section2.2 Subset Sums题解&代码
- USACO 2.2 Subset Sums dp
- USACO Section 2.2 Subset Sums - 01背包的思想
- USACO 2.2 Subset Sums (subset)
- DP USACO 2.2.2 Subset Sums 集合
- USACO-Section2.2 Subset Sums [动态规划]
- usaco ★Subset Sums 集合
- USACO / Subset Sums集合 (DP)
- USACO:2.2.2 Subset Sums 集合和
- USACO - Chapter2 Section 2.2 - Subset Sums
- USACO - 2.2 Subset Sums(DP)
- USACO section 2.2 Subset Sums(DP,背包)
- USACO section 2.2 Subset Sums(DP,背包)
- USACO2.22 Subset Sums(母函数)