这个周真是够呛,接连的考试考得我一阵心里凉凉QAQ。复变还没怎么看就考了,估计就算过了也的不了多少分。不过这波考试过去总算有相当长的时间去复习常微分(必须在这科打翻身仗)。而且接下来有充足的时间去联系学习acm。下面总结一下最近学的新知识,和做的一些题目吧,零零散散的,总结重要的。
母函数:(这是漏掉整理的一部分,非常好用,可以解决一类问题)
定义:对于任意数列a0,a1,a2…an 即用如下方法与一个函数联系起来:G(x) = a0 + a1x + a2x*2 + a3x^3...+ anx^n则称G(x)是数列的生成函数。
其实我的理解就是一种将组合数学的问题通过映射,将实际问题建立一一映射,映射到幂级数上,利用幂级数的加(与)与乘(或)的关系解决问题。
举个例子:有3个1元,1个2元,1个5元,问能够组成多少种价值的钱。 不难看出可以有 1,2,3,4,5,,,,10。那么我们设a*x^n,代表n元硬币又a个,那么设(1+x+x^2+x^3)(1+x^2)(1+x^5),如果把它展开,不难发现b*x^i代表 i 元硬币有b个的答案,因为上式(1+x+x^2+x^3)代表1元选0个或选1个或选2个或选3个,而选1元和选2元是互不影响的,所以用乘起来,表示一种或的关系,所以就是一种一一映射了。
我讲的不大好,推荐几位大佬的博客http://blog.youkuaiyun.com/xiaofei_it/article/details/17042651 和 http://blog.youkuaiyun.com/metalseed/article/details/8046656
又在杭电上水了几题。
hdu 1028 Ignatius and the Princess III
题意:给出一个数n,找出用1,2,,,n选出若干不同种的数加和成n,求多少种组法。比如:
4 = 4;
4 = 3 + 1;
4 = 2 + 2;
4 = 2 + 1 + 1;
4 = 1 + 1 + 1 + 1;
这个题的母函数就很简单(1+x+x^2+...x^n)(1+x^2+x^4+...)....(1+x^n)展开这个多项式就行了,至于展开多项式具体方法,看代码注释吧。
int c1[1000], c2[1000];
int val[1000];
int main()
{
int n;
while(cin>>n)
{
for(int i=1;i<=n;i++)//存有多少种指数
{
val[i]=i;
}
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(int i=0;i<=n;i++)//相当于(1+x+x^2+...x^n),利用c1作标记指数 i 的x^i前的系数
{
c1[i]=1;
}
for(int i=2;i<=n;i++)//所有指数依次合并
{
for(int j=0;j<=n;j++)//两个多项式合并
{
for(int k=0;k+j<=n;k+=val[i])
{
c2[j+k]+=c1[j];
}
}
for(int j=0;j<=n;j++)//传导给c1,在继续合并。
{
c1[j]=c2[j];
c2[j]=0;
}
}
cout<<c1[n]<<endl;
}
return 0;
}
hdu 1398 Square Coins
题意:有17中硬币,面额分别为1 , 2^2 , 3^2 , 4^2 ,,,,17^2。给出一个数n,求有多少种组法,相当于和上面的题一样。很简单。
int c1[100005],c2[100005];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(int i=0;i<=n;i++)
{
c1[i]=1;
}
for(int i=2;i*i<=n;i++)//所有i*i小于n的幂级数多项式
{
for(int j=0;j<=n;j+=(i*i))//注意这里加的是i*i。
{
for(int k=0;k+j<=n;k++)
{
c2[j+k]+=c1[k];
}
}
for(int j=0;j<=n;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
cout<<c1[n]<<endl;
}
return 0;
}
母函数的题目还算好做,主要是这一类的题。下整理这两道有代表性的吧,刚做的其他母函数题更水。
另外,还打了一次牛客网比赛,我还是一如既往的菜,至少让我长记性0也是完全平方数。另外在vj上找到了其他数学专题,是其他学校的吧,接下来两周,概率期望,全面开始。
对了还有莫比乌斯反演下一篇整理一下。