自己还是太菜了,算法还是很难。。。这么简单的题目竟然花费了我很多时间。。。在这里我用一个小白的角度剖析一下这道题目。

晓萌希望将1到N的连续整数组成的集合划分成两个子集合,且保证每个集合的数字和是相等。例如,对于N=3,对应的集合{1,2,3}能被划分成{3} 和 {1,2}两个子集合.

这两个子集合中元素分别的和是相等的。

对于N=3,我们只有一种划分方法,而对于N=7时,我们将有4种划分的方案。

输入包括一行,仅一个整数,表示N的值(1≤N≤39)。

输出包括一行,仅一个整数,晓萌可以划分对应N的集合的方案的个数。当没发划分时,输出0。

样例输入

7

样例输出

  

4

为了做出来这道题目我看了很多博客,发现很多人用一维的方法去处理这道题目,不过鉴于我太菜了。。。所以还是用二维去理解然后做题吧,,
这道题目关键点在于发现大问题可以归于小问题的求解,在分析这道题目的时候,我们能发现问题可以抽象成01背包问题,即:第i个数要还是不要的问题。
也就是说我的一个大问题可以分解成两个子问题:①当现在考虑的物品范围是1~i-1的时候,我们的背包容量已经达到了j,这时候我们不要第i个物品(抽象成这道题目就是:当我们不要第i个数时,我们前i-1个数中已经有满足相加为j的组合)
②考虑范围也是1~i-1,这个时候我们要将第i个物品放到背包中,也就是说我们要使用数组DP[i-1][j-i]存的数据(在这里我要稍微解释一下这个DP[][]数组的含义:第一个维度表示我们现在考虑的是1~i个数,然后第二维度表示我的背包最多存储的值的大小),在这里我们可以这么理解:就是我如果在包里放入第i个数,那就意味着我如果要让最后数的总和达到j,那就要调用j-i这个里面的数据。 上面的分析有可能有点混乱,但是总结一点,那就是我DP[i][j]里面的数据是有前面已经生成的两个数据组成:DP[i][j]=DP[i-1][j]+DP[i-1][j-1]。 下面换一个解释方法:(如果已经懂了的可以跳过)

为避免词语重复,下面说S中第i个元素时,就是指第i个整数。

假设此时,S中前i-1个元素都判断完了,紧接着应该判断第i个元素,与此同时,子集合的整数和被限定为sum,那么这第i个元素要不要被加入子集合呢?对此,我们做如下推断:

1:如果这第i个元素本身大于子集合的整数和sum,即i>sum,那么这第i个元素肯定不能加入子集合,否则就超出子集合整数和限制了。此时:F(i, sum)=F(i-1, sum),意思就是在相等的子集合整数和限制下,既然第i个元素没被加入,那么判断完第i个元素后的整数选取方案与判断完第i-1个数时的方案应该是相同的。

2:如果这第i个元素小于子集合整数和,那么就有两种考虑:

2.1:坚持不把第i个元素放入子集合,那么此时整数的选取方案仍然有F(i-1, sum)种。

2.2:如果把第i个元素放入了子集合,那么此时整数的选取方案有F(i-1, sum-i)种,sum-i的含义在于既然要放入第i个元素,就要给它留下足够的空间。F(i-1, sum-i)是在肯定要放入元素i的情形下,放入元素i前,整数的选取方案。

也即是说,i<=sum时,F(i, sum)=F(i-1, sum)+F(i-1, sum-i)

综上可得

这个就是DP问题的关键部分的函数,剩下的步骤就是付给初值然后动态赋值。

#include<iostream>
using namespace std;
long long DP[][];//里面放的是情况数,注意类型,我就是因为类型被wa了好多次。。。。。
int main(){ int n;
cin>>n;
int s=(+n)*n/; if(s%==) {
cout<<;return ;}//这个是判断是否能够分成两组,因为每一组的值都是总和的一半,所以总和必须是偶数。
int ss = s/; DP[][]=;//这个就是关键的初值:当我背包的重量为0时,考虑前0个数,也就是把0放到包里这一种情况,所以情况数为1. for(int i=;i<=ss;i++){
DP[][i] = ;//当我背包容量为i时(i>0),这个时候在前0个数中无法找到任何组能满足我的这个需求,所以为0.
}
for(int i=;i<=n;i++){
for(int h=;h<=ss;h++){
if(h<i) DP[i][h]=DP[i-][h];//当h<i时,意味着背包需求为h,但是我i已经大于h了,意味着肯定不能把i放进背包,所以当前情况为上一种情况。
else{
DP[i][h]=DP[i-][h]+DP[i-][h-i];//这就是那个动态方程(上面内容已经讲了)
}
}
}
cout<<DP[n][ss]/<<endl;//输出的时候要/2。因为我的里面分成了两组,得出的结果是有一半其实属于同一个情况的 }

在这里放上代码。

动态规划确实不太好理解,以后还是多写题目吧。。。太菜了
Orz。。。 ----------------------------------------------------------------------------------Made By 蒟蒻 Pinging。。

动态规划---等和的分隔子集(计蒜课)、从一个小白的角度剖析DP问题的更多相关文章

  1. 算法复习周------“动态规划之‘最长公共子序列’”&&《计蒜课》---最长公共子串题解

    问题描述: 这个问题其实很容易理解.就是给你两个序列X={x1,x2,x3......xm} Y={y1,y2,y3......ym},要求找出X和Y的一个最长的公共子序列. 例:Xi={A, B, ...

  2. German Collegiate Programming Contest 2015 计蒜课

    // Change of Scenery 1 #include <iostream> #include <cstdio> #include <algorithm> ...

  3. 计蒜课--2n皇后、n皇后的解法(一般操作hhh)

    给定一个 n*nn∗n 的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入 nn 个黑皇后和 nn个白皇后,使任意的两个黑皇后都不在同一行.同一列或同一条斜线(包括正负斜线)上,任意的两个白皇后都 ...

  4. 计蒜课/ 微软大楼设计方案/中等(xjb)

    题目链接:https://nanti.jisuanke.com/t/15772 题意:中文题诶- 思路:对于坐标为p1(x1, y1), p2(x2, y2) 的两个核心, 其中 x1 <= x ...

  5. 计蒜课/UCloud 的安全秘钥(hash)

    题目链接:https://nanti.jisuanke.com/t/15768 题意:中文题诶- 思路:直接hash就好了,当时zz了没想到... 代码: #include <iostream& ...

  6. [noip模拟]计蒜姬<BFS>

    Description 兔纸们有一个计蒜姬,奇怪的是,这个计蒜姬只有一个寄存器X.兔纸们每次可以把寄存器中的数字取出,进行如下四种运算的一种后,将结果放回寄存器中.1.X=X+X2.X=X-X3.X= ...

  7. 运用NP求解 “跳跃游戏”---计蒜客

    计蒜客里面有一道“跳跃游戏的问题” 给定一个非负整数数组,假定你的初始位置为数组第一个下标. 数组中的每个元素代表你在那个位置能够跳跃的最大长度. 你的目标是到达最后一个下标,并且使用最少的跳跃次数. ...

  8. 计蒜客 作弊揭发者(string的应用)

    鉴于我市拥堵的交通状况,市政交管部门经过听证决定在道路两侧安置自动停车收费系统.当车辆驶入车位,系统会通过配有的摄像头拍摄车辆画面,通过识别车牌上的数字.字母序列识别车牌,通过连接车管所车辆信息数据库 ...

  9. (计蒜客)UCloud 的安全秘钥

    UCloud 的安全秘钥 题意 给出一个数组 s 串,和数组 t 串,那么如果两者长度相同且两者所含的数字全部相同,则说这两个串相似. 给定原始串 S ,以及 m 个询问 T 串,问 S 串有多少个连 ...

随机推荐

  1. 【遍历二叉树】04二叉树的层次遍历【Binary Tree Level Order Traversal】

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树,返回他的层次遍历的 ...

  2. python 3 serial module install

    /************************************************************************* * python 3 serial module ...

  3. React 版 V2EX 社区( react & react-router & axios & antd ui)

    目录 项目简介 在线演示 截图演示 踩坑 项目简介(1/4) Github: https://github.com/bergwhite/v2ex-react 项目使用React.Reac-router ...

  4. 【转】 Pro Android学习笔记(四五):Dialog(2):DialogFragment

    [-] 重写onCreateView 通过onCreateView设置UI和按键反馈 信息保存 重写onCreateDialog DialogFragment的实例newInstance()已经在上一 ...

  5. C#设计模式(12)——享元模式

    一.概念 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使用.使用外观模式时,我们创建了一个统一的类,用来包装子系统中一个或多个复杂的类,客户端可以直 ...

  6. Project Server 2016 RestAPI调用测试

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...

  7. content-disposition attachment filename 在Firefox和IE中得到不同的结果

    在Firefox中需要把filename 用双引号包起来,才能得到想要的名字,不然如果含有空格,会丢掉空格后面的部分.而IE会把空格转为_,因此也需要HttpUtility.UrlPathEncode ...

  8. $.parseJSON失效的问题

    郁闷死,之前都是用parseJSON来解析json的,这次竟然不行了,提示parseJSON is not a function,jquery是1.72的,经过前端的帮忙,var objs = JSO ...

  9. Elasticsearch之curl创建索引库

    关于curl的介绍,请移步 Elasticsearch学习概念之curl 启动es,请移步 Elasticsearch的前后台运行与停止(tar包方式) Elasticsearch的前后台运行与停止( ...

  10. day01_虚拟机与主机之间ip配置

       虚拟机1: centos_ node1 虚拟机2:centos_node2 宿主主机虚拟机ip配置: vmnet1 来自为知笔记(Wiz)