程序员互动联盟(第一届编程大赛第一题)

116 篇文章 2 订阅
35 篇文章 0 订阅

题目大意:

将1到N的连续整数组成的集合划分成两个子集合,且保证每个集合的数字和是相等的。

例如,输入N=3,对应的集合{1,2,3} 可以被划分为{3},{1,2}两个子集合,这两个子集合中元素分别的和是相等的。输入7,输出4


思路:

首先1,2,3……N所有元素的和为 S= N*(N+1)/2, 如果S不能被2整除,那么一定不能划分,否则各个集合里面的元素之和为 S = N*(N+1)/4,下面运用动态规划的思想,令count[i] 表示 和为 i 的方案数目,那么 count[j] = count[j] + count[j-i] , 表示和为 j 的方案数,等于原先的值 加上 和为 j-i 的方案数。 也就是说,没有加 i 之前的方案数 现在加上i之后,和变为 j, 那么和为j的方案数也应该加上 和为j-i的方案数,有点绕。。。


很经典的动态规划的例子,刚开始做竟然没想起来。


#include <iostream>
using namespace std;

#define N 40

int main(){
    int n,s;
    cin>>n;
    int count[400]; //该数组count[i]表示和为i的方案数
    memset(count,0,sizeof(count));
    s = n*(n+1)/2;
    if(s%2!=0)
        cout<<0<<endl;
    s = s/2;
    count[0] = 1;
    for(int i=1;i<=n;i++){
        for(int j=s;j>=i;j--){
            count[j] += count[j-i];
        }
    }
    cout<<count[s]/2<<endl;
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值