DP-母函数
DP---母函数
先由钱币兑换问题开始 http://acm.hdu.edu.cn/showproblem.php?pid=1284
Problem Description
在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法。请你编程序计算出共有多少种兑法。
Input
每行只有一个正整数N,N小于32768。
Output
对应每个输入,输出兑换方法数。
这道题有三种解法(参照此博客http://www.cnblogs.com/Findxiaoxun/p/3574907.html)
完全背包的解法很容易想到,模板性质的。
第二种技巧性的就会强一点。这样想,先只考虑1和3,不是1,就是3,全1的只有一种;每三个1就可以兑换一个3,方法数就有n/3种。再考虑2的情况,全部是2和1的情况,实际上,去掉i个3,就可以变成只含有1和2的情况,而类似的,只含有1和2的情况,可以有(n-3*i)/2种,此时只需要把这些方法数加起来就可以了。
第三种就是母函数了,在此引用下这位大神的博客(http://www.wutianqi.com/?p=596),
Woo讲的很好了,尤其是算法归纳的过程,不过个人感觉少了对代码的分析,这里我毛遂自荐,来讲下我的理解: 大家在学习母函数的时候,一定要记住理解这样一句话:母函数算法其实就是模拟手算多项式乘法。
首先要看Woo的那篇文章,最重要的理解是:
① 、首先对c1初始化,由第一个表达式(1+x+x^2+..x^n)初始化,把质量从0到n的所有砝码都初始化为1.
② 、 i从2到n遍历,这里i就是指第i个表达式,上面给出的第二种母函数关系式里,每一个括号括起来的就是一个表达式。
③、j 从0到n遍历,这里j就是(前面i個表达式累乘的表达式)里第j个变量,(这里感谢一下seagg朋友给我指出的错误,大家可以看下留言处的讨论)。如(1+x)(1+x^2)(1+x^3),j先指示的是1和x的系数,i=2执行完之后变为 (1+x+x^2+x^3)(1+x^3),这时候j应该指示的是合并后的第一个括号的四个变量的系数。
④ 、 k表示的是第j个指数,所以k每次增i(因为第i个表达式的增量是i)。
⑤ 、把c2的值赋给c1,而把c2初始化为0,因为c2每次是从一个表达式中开始的。
Woo这里是根据题目来说的,而且,其实他的代码里Num那个地方,其实是有两种的,一般情况下。 来看下母式子: (1+x+x^2+x^3+x^4+..)(1+x^2+x^4++..)(1+x^3+x^6+..) 第一个括号指的是1分的,在拆分第一个括号的之前,1分的能够构成数m,那么c1[m]=1;如果是有a个1分的,那么1分一直a,c1[a]=1;然后开始拆分第一个括号,就是把第一个括号和第二个括号合并,我们手算多项式乘法,先按括号一的那个1,乘(第二个括号里的内容),很自然的c2[i]+=c1[i],这里的c2[i]表示的是在这次的循环过程中,中间的结果,这句话理解不了的话,继续看。然后括号一的第二个元素x,x*(....)=x*1+x*x^2+x*x^4...=x+x^3+x^5...最终,它们会和第一次乘出来的结果同项合并,x^3+x^3=2*x^3,其他值都类似,那么,c2[3]+=c1[1];c1[i]就是保存的之前乘出来的x^i结果的系数,等这一次乘完,c2[i]保存了最终的结果,那就把它的值都转移到c1里面去,然后c2又空。继续分解括号。
举个例子:
3个1分的硬币,1个2分的,2个3分的。
(1+x+x^2+x^3)(1+x^2)(1+x^3+x^6)
1.初始化:
0 1 2 3 4 5 6 7 8 9
c1: 1 1 1 1 0 0 0 0 0 0
C2全0
2.对第一个括号的1*(1+x^2),(i=2,j=0)得到
0 1 2 3 4 5 6 7 8 9
C2: 1 0 1 0 0 0 0 0 0 0
就是说,原来2个1可以组成2,现在,一个2就能替换,有1种方法。
3. X*(1+x^2) (i=2;j=1)
0 1 2 3 4 5 6 7 8 9
C2: 1 1 1 1 0 0 0 0 0 0
4. X^2*(1+x^2) j=2
0 1 2 3 4 5 6 7 8 9
C2: 1 1 2 1 0 0 0 0 0 0
5. x^3*(1+x^2) j=3
0 1 2 3 4 5 6 7 8 9
C2:1 1 2 2 0 0 0 0 0 0
把c2的值全都转移到c1里 i=3
剩下的步骤也是如此。
就是模拟手工计算多项式乘法。
Woo的博客介绍的几道题都挺不错,现在外面来把这个算法真正的理解运用下:
HDU1711,题意就是说,给价值不同的一些物品,让你把它们分成和尽可能接近的两堆。
一种很巧妙的思路是,转换成完全背包,或者是01背包。因为动态规划解决的问题一般是最××的问题,最多,最少,最接近,等等。而这个题,可以看成是sum/2空间的背包,让你用那些物品装,尽可能装满。背包的代码我先附上,背包专辑我后续我会整理出来。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; ; ; int n,t,sum; int dp[maxm],v[maxn]; int main(){ ){ int a,b; n=;sum=; memset(v,,sizeof(v)); ;i<t;i++){ scanf("%d%d",&a,&b); while(b--){ v[n++]=a;//wa sum+=a; } } ; memset(dp,,sizeof(dp)); ;i<n;i++){ for(int j=sum2;j>=v[i];j--){ dp[j]=max(dp[j],dp[j-v[i]]+v[i]); } } // for(int i=0;i<=sum2;i++)printf("%d ",dp[i]); int ans=max(dp[sum2],sum-dp[sum2]); printf("%d %d\n",ans,sum-ans); } ; }
再来看母函数的思路。可以这样想,因为题中对价值的限制为50,也就是说,只有50种值,有50种面值个数不同的硬币,要你求出,能表示出的最接近总数一半的那个值。转换为了母函数问题。来看i,j,k 50种面值,1的可以直接先处理,那么i=2 to 50,而j的范围就是0 to sum,k则是(k=0;k+j<=sum&& k<i*num[i];k+=i)k的限制也很好理解,因为只有num[i]个i面值的硬币,则多项式最多就能乘到x^(i*num[i])。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; ],c2[]; ]; int sum; int main(){ int n; ){ sum=; int a,b; memset(data,,sizeof(data)); memset(c1,,sizeof(c1)); memset(c2,,sizeof(c2)); ;i<n;i++){ scanf("%d%d",&a,&b); data[a]=b; sum+=a*b; } ;i<=data[];i++)c1[i]=; ;i<=;i++){ ;j<=sum;j++){ ;j+k<=sum&&k<=i*data[i];k+=i) c2[j+k]+=c1[j]; } ;j<=sum;j++){ c1[j]=c2[j];c2[j]=; } } ; while(!c1[x]){x--;} int ans=max(x,sum-x); printf("%d %d\n",ans,sum-ans); } ; }
DP-母函数的更多相关文章
- hdu 1284 钱币兑换问题 (递推 || DP || 母函数)
钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- E比昨天更多的棒棒糖(Easy+Hrad)(华师网络赛)(DP||母函数||背包优化)
Time limit per test: 2.0 seconds Memory limit: 512 megabytes 唐纳德先生的某女性朋友最近与唐纳德先生同居.该女性朋友携带一 baby.该 b ...
- HihoCoder1339 Dice Possibility(概率DP+母函数)
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 What is possibility of rolling N dice and the sum of the numb ...
- 【BZOJ-3696】化合物 树形DP + 母函数(什么鬼)
3696: 化合物 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 165 Solved: 85[Submit][Status][Discuss] D ...
- 大概是:整数划分||DP||母函数||递推
整数划分问题 整数划分是一个经典的问题. Input 每组输入是两个整数n和k.(1 <= n <= 50, 1 <= k <= n) Output 对于每组输入,请输出六行. ...
- 组合数学 - 母函数的变形 --- hdu 1171:Big Event in HDU
Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- HDU 1028 Ignatius and the Princess III:dp or 母函数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1028 题意: 给你一个正整数n,将n拆分成若干个正整数之和,问你有多少种方案. 注:"4 = ...
- hdu1028(母函数+DP)
题目信息:求分解整数n的个数q(n);能够母函数或者DP http://acm.hdu.edu.cn/showproblem.php?pid=1028 AC代码: /***************** ...
- HDU 1398 Square Coins(母函数或dp)
Square Coins Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- HDU 1028 Ignatius and the Princess III (母函数或者dp,找规律,)
Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
随机推荐
- C++中的set和java的hashset有何区别?
以前对C++的STL容器烂熟于心,两年没碰过C++了,现在已经很生疏了.工作原因转战java,对java的容器不甚了解,特别是每看到一种容器,不由自主地拿起和C++对比.C++中的set和java的h ...
- [转载]ubuntu的版本
http://bbs.chinaunix.net/thread-2126589-2-1.html 希望他说的是对的 ubuntu 发布的linux里面有一个非常具有迷惑性的版本-desktop.因为 ...
- Excel下用SQL语句实现AVEDEV函数功能
Excel下AVEDEV函数返回一组数据点到其算术平均值的绝对偏差的平均值. AVEDEV 是对一组数据中变化性的度量.最常见的应用就是统计平均分差. 但是如果在Excel中写SQL进行一些复杂的统计 ...
- android开发 drawtext的开始坐标位置
我们canvas绘制文字的遇到一个不知道drawtext(str,x,y,paint) 中的x.y坐标值怎么定义,,如果设为(0,0)的话文字就不会出来了.因此查找到一下资料: 问:canvas.d ...
- Netsharp快速入门(之11) 销售管理(开发销售订单工作区)
作者:秋时 杨昶 时间:2014-02-15 转载须说明出处 4.3 销售订单开发 4.3.1 部件工作区设置 1.创建部件工作区,建工作区向导中要注意勾选组合并系部分.具体要建立的部 ...
- Java8 Lambda sample (iwantmoon.com出品)
转载请注明出处:http://iwantmoon.com/Post/83a4497a74674612834965857e7bc044 .Net转到Java来,不知不觉已经有两年了,之前已经用习惯的li ...
- BZOJ 4500: 矩阵 差分约束
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=4500 题解: 从行向列建边,代表一个格子a[i][j],对每个顶点的所有操作可以合并在一 ...
- hibernate学习笔记--可选的配置属性
3.4. 可选的配置属性 有大量属性能用来控制Hibernate在运行期的行为. 它们都是可选的, 并拥有适当的默认值. 警告: 其中一些属性是"系统级(system-level)的&qu ...
- BZOJ2694: Lcm
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2694 题解:令f[i]表示i是否有平方因子,则f[i]是积性函数,mu[i]表示莫比乌斯函数. ...
- JS中函数的基础知识
函数 一. 函数定义 函数又叫方法,在程序里面函数是用来执行某些特定功能的代码.为了减少重复使用代码,可以把特定功能的代码做成函数,需要使用时拿出来调用.alert();就是一个很常见的.简单的函数 ...