USACO 2.2.2 Subset Sums

一.题目描述

For many sets of consecutive integers from 1 through N (1 <= N <= 39), one can partition the set into two sets whose sums are identical.

For example, if N=3, one can partition the set {1, 2, 3} in one way so that the sums of both subsets are identical:
•{3} and {1,2}

This counts as a single partitioning (i.e., reversing the order counts as the same partitioning and thus does not increase the count of partitions).

If N=7, there are four ways to partition the set {1, 2, 3, ... 7} so that each partition has the same sum:
•{1,6,7} and {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}

Given N, your program should print the number of ways a set containing the integers from 1 through N can be partitioned into two sets whose sums are identical. Print 0 if there are no such ways.

Your program must calculate the answer, not look it up from a table.

PROGRAM NAME: subset

INPUT FORMAT
The input file contains a single line with a single integer representing N, as above.
SAMPLE INPUT (file subset.in)
7


OUTPUT FORMAT

The output file contains a single line with a single integer that tells how many same-sum partitions can be made from the set {1, 2, ..., N}. The output file should contain 0 if there are no ways to make a same-sum partition.

SAMPLE OUTPUT (file subset.out)
4

二.题目分析

  题目等效于从1,2,,,,N中找到和为sum/2的种类数,可以使用DFS搜索所有组合,但是肯定会超时,如代码1中。采用动态规划的方式,重要的是找到转态转移方程.

  dp[i,j]表示在前i个序列中和为j的个数,可以这样想,对于第i个物品,当i>j时,我们要想得到和为j,肯定不能放入i,此时dp[i,j]=dp[i-1,j];当i<=j时,我们可以选择放入或者不放入两种情况,当不放入时情况同上,当放入i时,由于i的价值即值是i,因此这时的种类数应该等于前i-1个序列中何为j-i的种类数,得到dp[i,j]=dp[i-1,j-i];

综合上述分析,可以得到:

   j<i时,     dp[i,j]=dp[i-1,j]

   j>=i时,   dp[i,j]=dp[i-1,j]+dp[i-1,j-i];

采用简化的方式,可以得到  j>=i时,dp[j] += dp[j-i];

三.代码

1.DFS (TLE)

#include <stdio.h>
#include <stdlib.h>
int cn,sum,N;

void DFS(int n,int total)      //total after add n
{
    if(n==N+1)
		return ;

    if(total>sum)
		return;

    if(total==sum)
    {
        cn++;
        return ;
    }

	//(n,total);
    DFS(n+1,total+n+1);   //深入方向搜索

	DFS(n+1,total);  //水平方向搜索

}

int main()
{
    int i;
	FILE *in=NULL,*out=NULL;
    in=fopen("subset.in","r"),out=fopen("subset.out","w");

    if(!in||!out)
    {
        printf("file open error!\n");
        return -1;
    }

    fscanf(in,"%d",&N);
    sum=0;
    for(i=1;i<=N;i++)
        sum+=i;

    if(sum%2!=0)
    {
        printf("0\n");
        return 0;
    }

    cn=0;   //all possible
    sum /=2;

    DFS(0,0);

    fprintf(out,"%d\n",cn/2);

    return 0;
}

2.DP(AC)

#include<stdio.h>
#include<stdlib.h>
#define MAX 800
int main()
{
	FILE *in,*out;
	long long**f;
	int i,j,N,sum=0,s=1;
	in=fopen("subset.in","r");
	out=fopen("subset.out","w");
	if(in==NULL||out==NULL)
	{
		printf("error!\n");
		return -1;
	}
	fscanf(in,"%d",&N);

    f=(long long**)malloc(MAX*sizeof(long long*));
    for(i=0;i<MAX;i++)
        f[i]=(long long*)malloc(MAX*sizeof(long long));

    for(i=0;i<MAX;i++)
        for(j=0;j<MAX;j++)
            f[i][j]=0;

	sum=N*(N+1)/2 ;

	if(sum%2!=0)
	{
		fprintf(out,"0\n");
		return 0;
	}
	sum=sum/2;
	f[1][1]=1;
	f[1][0]=1;
	for(i=2;i<=N;i++)
	{
		for(j=0;j<=sum;j++)
		{
			if(j<i)    //肯定是不能取i
			 f[i][j]=f[i-1][j];
			else     //分为取i  /  不取i
			 f[i][j]=f[i-1][j]+f[i-1][j-i];
		}
	}


    fprintf(out,"%lld\n",f[N][sum]/2);
	return 0;
}


3.DP(AC)

#include <fstream>
using namespace std;
const unsigned int MAX_SUM = 1024;
int n;
unsigned long long int dyn[MAX_SUM];
ifstream fin ("subset.in");
ofstream fout ("subset.out");

int main() {
    fin >> n;
    fin.close();
    int s = n*(n+1);
    if (s % 4) {
        fout << 0 << endl;
        fout.close ();
        return ;
    }
    s /= 4;
    int i, j;
    dyn [0] = 1;
    for (i = 1; i <= n; i++)
        for (j = s; j >= i; j--) 
            dyn[j] += dyn[j-i];
    fout << (dyn[s]/2) << endl;
    fout.close();
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧农业是一种结合了现代信息技术,包括物联网、大数据、云计算等,对农业生产过程进行智能化管理和监控的新模式。它通过各种传感器和设备采集农业生产中的关键数据,如大气、土壤和水质参数,以及生物生长状态等,实现远程诊断和精准调控。智慧农业的核心价值在于提高农业生产效率,保障食品安全,实现资源的可持续利用,并为农业产业的转型升级提供支持。 智慧农业的实现依赖于多个子系统,包括但不限于设施蔬菜精细化种植管理系统、农业技术资料库、数据采集系统、防伪防串货系统、食品安全与质量追溯系统、应急追溯系统、灾情疫情防控系统、农业工作管理系统、远程诊断系统、监控中心、环境监测系统、智能环境控制系统等。这些系统共同构成了一个综合的信息管理和服务平台,使得农业生产者能够基于数据做出更加科学的决策。 数据采集是智慧农业的基础。通过手工录入、传感器自动采集、移动端录入、条码/RFID扫描录入、拍照录入以及GPS和遥感技术等多种方式,智慧农业系统能够全面收集农业生产过程中的各种数据。这些数据不仅包括环境参数,还涵盖了生长状态、加工保存、检验检疫等环节,为农业生产提供了全面的数据支持。 智慧农业的应用前景广阔,它不仅能够提升农业生产的管理水平,还能够通过各种应用系统,如库房管理、无公害监控、物资管理、成本控制等,为农业生产者提供全面的服务。此外,智慧农业还能够支持政府监管,通过发病报告、投入品报告、死亡报告等,加强农业产品的安全管理和质量控制。 面对智慧农业的建设和发展,存在一些挑战,如投资成本高、生产过程标准化难度大、数据采集和监测的技术难题等。为了克服这些挑战,需要政府、企业和相关机构的共同努力,通过政策支持、技术创新和教育培训等手段,推动智慧农业的健康发展。智慧农业的建设需要明确建设目的,选择合适的系统模块,并制定合理的设备布署方案,以实现农业生产的智能化、精准化和高效化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值