Subset Sums

本文针对USACO子集计数问题提供了一种C++实现方案,通过动态规划方法计算总和可以被平均分配到两个子集中的方案数量。关键步骤包括计算总和、判断是否能平均分配、利用动态规划数组记录子集和出现的次数,并最终输出有效子集的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem:

http://ace.delos.com/usacoprob2?a=GDaP3qeGiYp&S=subset


My Answer:

/*
ID:iby071
LANG:C++
TASK:subset
*/

#include<iostream>
#include<fstream>
using namespace std;

int main()
{	ifstream fin("subset.in");
	ofstream fout("subset.out");
	int n,sum,high;
	unsigned long int *dp;
	fin>>n;
	
	sum=(1+n)*n>>1;			//>>1即除以2
	if((sum&1)==1){fout<<'0'<<endl;return 0;}		//&1即取个位


	high=sum>>1;
	dp=new unsigned long int [high+1];
	for(int i=0;i<high+1;++i)
		dp[i]=0;
	
	dp[0]=1;

	for(int i=1;i<=n;++i)
		for(int j=high;j>=i;--j)
			dp[j]=dp[j]+dp[j-i];			//j>i情况下,前i项和为j的组合方式书dp[(当前i下)j]=dp[(i-1情况下)j]+dp[(i-1情况下)j-i]
	

	fout<<(dp[high]>>1)<<endl;				//每一种子集对应的组合方式与它的补集对应的组合方式重复,故除以2

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值