做题笔记——“动态规划”:子集的和
来源:互联网 发布:php过滤敏感词的例子 编辑:程序博客网 时间:2024/06/03 09:11
经过了许久的学习,就应该将所学沉淀下来。
那么今天小编记录的,是一道挺有趣的编程题——子集的和。
这道题可以用动态规划(DP)来解决。这次我做的是新学的动态规划类型的题:子集的和……
题目描述
对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字之和是相等的。
举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,他们每个的所有数字和是相等的:
{3} and {1,2}
这是唯一一种分法(交换集合位置被认为是同一种划分方案,因此不会增加划分方案总数)
如果N=7,有四种方法能划分集合{1,2,3,4,5,6,7},每一种分发的子集合各数字和是相等的:
{1,6,7} 和 {2,3,4,5} 1+6+7=2+3+4+5
{2,5,7} 和 {1,3,4,6}
{3,4,7} 和 {1,2,5,6}
{1,2,4,7} 和 {3,5,6}
给出N,你的程序应该输出划分方案总数,如果不存在这样的划分方案,则输出0。
输入
第1行:一个整数N
输出
第1行:输出划分方案总数,如果不存在则输出0。
样例输入
7
样例输出
4
我们拿到这道题,首先应该判断它应该用哪种算法(思想)来做。
因为这道题的方案数量只与局部最优有关,而且可以划分阶段,所以我选择通过动态规划做。
那么怎么利用动态规划呢?
动态规划的本质其实就是记忆化搜索,但动归是以递推的形式呈现的,动归有以下一些步骤。
1.利用数组表示状态
2.赋初值
3写出动态转移方程式
4利用求解
该题就是一个例子了!
#include<cstdio>#include<algorithm>using namespace std;int n,f[40][808],sum;//利用f数组储存状态f[i][j]代表着用前i个整数中加和为j的方案数int main(){ scanf("%d",&n);for(int i=1;i<=n;i++) {f[i][0]=1;sum+=i;} //如果前i个整数中加和为0,只有1个方案,用sum存总和if(sum&1) //其实就是sum%2==1{ printf("0"); return 0; //当总和都是奇数时,是不能分成相等的两个整数的 }for(int i=1;i<=n;i++) //通过i,j的范围,找f[i][j] for(int j=n*(n+1)/4;j>0;j--)if(j>=i)f[i][j]=f[i-1][j]+f[i-1][j-i]; //如果要加第i个数,那么i-1,加和要减去第i个数的值,也就是减去i;如果不加,只用i-1,。两种情况应该相加else f[i][j]=f[i-1][j]; //如果j<i,加和就不能减第i个数了,只有1种情况 printf("%d",f[n][n*(n+1)/4]); //前n个整数中加和为n*(n+1)/4的方案数即为解return 0;}
阅读全文
0 0
- 做题笔记——“动态规划”:子集的和
- 9.9递归和动态规划(四)——返回某集合的所有子集
- 子集和(动态规划)
- C++动态规划算法之子集的和
- 动态规划之子集和问题
- 子集和是否存在问题的动态规划和递归解
- 动态规划法--求数组中最大子集合的和
- 程序员面试金典: 9.9 递归和动态规划 9.4求某集合的所有子集
- 【动态规划】从子集和问题到背包问题
- 算法笔记——【动态规划】最大子段和
- 做动态规划题的步骤和例子(还在完善中)
- ACM学习笔记——动态规划
- 动态规划——背包问题笔记
- leetcode笔记—关于动态规划
- 做基础动态规划题目的方法
- 动态规划的一些笔记
- BZOJ 2064 浅谈状态压缩动态规划基础及lowbit枚举子集和
- 动态规划之背包做题报告
- POJ1785 Binary Search Heap Construction【笛卡尔树】
- iscsi
- 畅享大屏视界,iFunk S游戏本
- 容斥水体HDU
- 数组排序及去重
- 做题笔记——“动态规划”:子集的和
- 工作中一些工具的使用!
- 常用的排序算法集锦
- ActiveMq消息队列
- 如何使用Docker、Docker-Compose和Rancher搭建部署Pipeline(三)
- 除了选对主机,网站内容和用户体验更为重要
- EJB到底是什么
- git cherry-pick使用小结
- Android中自定义Toast视图和修改显示位置