<8/22>集训日记

今天上午看了些数学的博客,看到了一个母函数的题,没想到下午练习赛就用上了哈哈哈~
上午看的是HDOJ2082,找单词的一个题。
题目:
假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26。那么,对于给定的字母,可以找到多少价值<=50的单词呢?单词的价值就是组成一个单词的所有字母的价值之和,比如,单词ACM的价值是1+3+14=18,单词HDU的价值是8+4+21=33。(组成的单词与排列顺序无关,比如ACM与CMA认为是同一个单词)。
代码及注解如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=50;
int c1[N+10],c2[N+10],num[30];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(num,0,sizeof(num));
        for(int i=1;i<=26;i++)
        scanf("%d",&num[i]);
        memset(c1,0,sizeof(c1));    //c1[ ]保存当前得到的多项式各项系数
        memset(c2,0,sizeof(c2));    //c2[ ]保存每次计算时的临时结果
        c1[0]=1;                //相当于用X^0去乘以后面的多项式
        for(int i=1;i<=26;i++){     //要乘以26个多项式
            for(int j=0;j<=N;j++)   //c1的各项的指数
                for(int k=0;k<=num[i] && j+k*i<=N;k++)  //k*i表示被乘多项式各项的指数,(X^0*i + X^1*i + X^2*i + ……)
                    c2[j+k*i]+=c1[j];       //指数相加得j+k*i,加多少只取决于c1[j]的系数,因为被乘多项式的各项系数均为1
            for(int j=0;j<=N;j++){
                c1[j]=c2[j];
                c2[j]=0;
            }
        }
        int ans=0;
        for(int i=1;i<=N;i++)
            ans+=c1[i];
        printf("%d\n",ans);
    }
    return 0;
}
看了几个题好像都是这个模板,现在打算明天好好整理整理母函数的内容了哈哈。

然后下午练习赛的时候,把几个题读完,他俩就一人按住一个题开始怼了,我看到C题的时候,就觉得这是个排列组合题。
题目:(POJ3046)
有编号1到T个蚂蚁家族,每个家族有不同的蚂蚁数,问构成S只蚂蚁到构成B只蚂蚁共有多少种方式。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iomanip>
using namespace std;
int c1[10005],c2[10005],num[1005];
int main()
{
    int t,a,s,b,n;
    while((scanf("%d%d%d%d",&t,&a,&s,&b))!=EOF)
    {
    memset(num,0,sizeof(num));
    for(int i=0;i<a;i++)
    {
        cin>>n;
        num[n]++;
    }
    memset(c1,0,sizeof(c1));
    memset(c2,0,sizeof(c2));
    c1[0]=1;
    for(int i=1;i<=t;i++)
        {
            for(int j=0;j<=b;j++)
            {
                for(int k=0;k+j<=b&&k<=num[i];k++)
                {
                    c2[k+j]=(c2[k+j]+c1[j])%1000000;
                }
            }
            for(int j=0;j<=b;j++)
            {
                c1[j]=c2[j];
                c2[j]=0;
            }
        }
        int sum=0;
        for(int i=s;i<=b;i++)
        sum=(sum+c1[i])%1000000;
        cout<<sum<<endl;
    }
    return 0;
}
几乎就是把母函数的模板照搬上的,就改了改循环的范围。第一次出现的是RE,因为我在开始的时候没看题的数据范围,先随便写了个,写小了忘改了…然后是一次WA,我以为是又忘了考虑多组输入的事儿,结果改完还是WA,但试的几个样例都没问题,所以倒回去读了一遍题,才发现有一句Print only the LAST SIX DIGITS of this number, with no leading zeroes or spaces.所以加了两个%1000000就AC了。

比赛结束看到只有我们AC了这道题的时候还是挺兴奋的,“有一个攻数学的人就能比别的队多出一道题“这句话是真的。其实只能算运气好,母函数的东西并没有很深刻的理解,只是看了看模板,碰到简单题了。就算是激励自己继续提高吧,只有提高自己的实力才更具竞争力。
以上~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值