简单母函数专题

HDU 1028

Ignatius and the Princess III

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 13840    Accepted Submission(s): 9757 

Problem Description
"Well, it seems the first problem is too easy. I will let you know how foolish you are later." feng5166 says.
"The second problem is, given an positive integer N, we define an equation like this:   N=a[1]+a[2]+a[3]+...+a[m];   a[i]>0,1<=m<=N; My question is how many different equations you can find for a given N. For example, assume N is 4, we can find:   4 = 4;   4 = 3 + 1;   4 = 2 + 2;   4 = 2 + 1 + 1;   4 = 1 + 1 + 1 + 1; so the result is 5 when N is 4. Note that "4 = 3 + 1" and "4 = 1 + 3" is the same in this problem. Now, you do it!"
 
Input
The input contains several test cases. Each test case contains a positive integer N(1<=N<=120) which is mentioned above. The input is terminated by the end of file.
 
Output
For each test case, you have to output a line contains an integer P which indicate the different equations you have found.
 
Sample Input
4 10 20
 
Sample Output
5 42 627
 
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 10000

int n;
int c1[N];
int c2[N];

int main()
{
    int i,j,k;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0;i<=n;i++)
        {
            c1[i]=1;
            c2[i]=0;
        }
        for(k=2;k<=n;k++)
        {
            for(i=0;i<=n;i++)
                for(j=0;i+j<=n;j+=k)
                    c2[i+j]+=c1[i];
                for(i=0;i<=n;i++)
                {
                    c1[i]=c2[i];
                    c2[i]=0;
                }
        }
        cout<<c1[n]<<endl;
    }
    return 0;
}

HDU 1085

Holding Bin-Laden Captive!

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 15692    Accepted Submission(s): 7019 

Problem Description
We all know that Bin-Laden is a notorious terrorist, and he has disappeared for a long time. But recently, it is reported that he hides in Hang Zhou of China!  “Oh, God! How terrible! ”
Don’t be so afraid, guys. Although he hides in a cave of Hang Zhou, he dares not to go out. Laden is so bored recent years that he fling himself into some math problems, and he said that if anyone can solve his problem, he will give himself up!  Ha-ha! Obviously, Laden is too proud of his intelligence! But, what is his problem? “Given some Chinese Coins (硬币) (three kinds-- 1, 2, 5), and their number is num_1, num_2 and num_5 respectively, please output the minimum value that you cannot pay with given coins.” You, super ACMer, should solve the problem easily, and don’t forget to take $25000000 from Bush!
 
Input
Input contains multiple test cases. Each test case contains 3 positive integers num_1, num_2 and num_5 (0<=num_i<=1000). A test case containing 0 0 0 terminates the input and this test case is not to be processed.
 
Output
Output the minimum positive value that one cannot pay with given coins, one line for one case.
 
Sample Input
1 1 3 0 0 0
 
Sample Output
4
 
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 1001000

int c1[N];
int c2[N];

int main()
{
    int top,i,j,a,b,c;
    while(scanf("%d%d%d",&a,&b,&c),a||b||c)
    {
        top=a+b*2+c*5;
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        for(i=0;i<=a;i++)  //第一项
        {
            if(i<=a) c1[i]=1;
        }
        
        for(i=0;i<=top;i++) //第二项
        {
            for(j=0;j<=b*2;j+=2)
            {
                c2[i+j]+=c1[i];
            }
        }
        for(i=0;i<=top;i++)
        {
            c1[i]=c2[i];
            c2[i]=0;
        }
        for(i=0;i<=top;i++) //第三项
        {
            for(j=0;j<=c*5;j+=5)
            {
                c2[i+j]+=c1[i];
            }
        }
        for(i=0;i<=top+1;i++)
        {
            if(!c2[i]) 
            {
                cout<<i<<endl;
                break;
            }
        }
    }
    return 0;
}

HDU 1398

Square Coins

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 8706    Accepted Submission(s): 5923 

Problem Description
People in Silverland use square coins. Not only they have square shapes but also their values are square numbers. Coins with values of all square numbers up to 289 (=17^2), i.e., 1-credit coins, 4-credit coins, 9-credit coins, ..., and 289-credit coins, are available in Silverland.  There are four combinations of coins to pay ten credits: 
ten 1-credit coins, one 4-credit coin and six 1-credit coins, two 4-credit coins and two 1-credit coins, and one 9-credit coin and one 1-credit coin. 
Your mission is to count the number of ways to pay a given amount using coins of Silverland.
 
Input
The input consists of lines each containing an integer meaning an amount to be paid, followed by a line containing a zero. You may assume that all the amounts are positive and less than 300.
 
Output
For each of the given amount, one line containing a single integer representing the number of combinations of coins should be output. No other characters should appear in the output. 
 
Sample Input
2 10 30 0
 
Sample Output
1 4 27
 

我擦、被坑了、题目叙述有问题,是no more than 300 ,不是less than 300

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 301

int c1[N],c2[N];
int sqare[]={0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289};

int main()
{
    int i,j,k;
    for(i=0;i<N;i++)
    {
        c1[i]=1;
        c2[i]=0;
    }
    for(k=2;k<=17;k++)
    {
        for(i=0;i<N;i++)
        {
            for(j=0;i+j<N;j+=sqare[k])

            {
                c2[i+j]+=c1[i];
            }
        }
        for(i=0;i<N;i++)
        {
            c1[i]=c2[i];
            c2[i]=0;
        }
    }
    int n;
    while(scanf("%d",&n) && n)
    {
        cout<<c1[n]<<endl;
    }
    return 0;
}

HDU 2079

选课时间(题目已修改,注意读题)

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 3052    Accepted Submission(s): 2390 

Problem Description
又到了选课的时间了,xhd看着选课表发呆,为了想让下一学期好过点,他想知道学n个学分共有多少组合。你来帮帮他吧。(xhd认为一样学分的课没区别)
 
Input
输入数据的第一行是一个数据T,表示有T组数据。 每组数据的第一行是两个整数n(1 <= n <= 40),k(1 <= k <= 8)。 接着有k行,每行有两个整数a(1 <= a <= 8),b(1 <= b <= 10),表示学分为a的课有b门。
 
Output
对于每组输入数据,输出一个整数,表示学n个学分的组合数。
 
Sample Input
2 2 2 1 2 2 1 40 8 1 1 2 2 3 2 4 2 5 8 6 9 7 6 8 8
 
Sample Output
2 445
 
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
#define N 42

int n,k;
int score[N];
int limit[N];

void cal()
{
    int i,j,kk;
    int c1[N],c2[N];
    memset(c1,0,sizeof(c1));
    memset(c2,0,sizeof(c2));
    for(j=0;j<=n && j<=score[1]*limit[1];j+=score[1])
    {
        c1[j]=1;
    }
    for(i=2;i<=k;i++)
    {
        for(j=0;j<=n;j++)
        {
            for(kk=0;kk+j<=n && kk<=limit[i]*score[i];kk+=score[i])
            {
                c2[j+kk]+=c1[j];
            }
        }

        for(j=0;j<=n;j++)
        {
            c1[j]=c2[j];
            c2[j]=0;
        }
    }
    cout<<c1[n]<<endl;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=k;i++)
        {
            scanf("%d%d",&score[i],&limit[i]);
        }
        cal();
    }
    return 0;
}

HDU 2082

找单词

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 4314    Accepted Submission(s): 3102 

Problem Description
假设有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认为是同一个单词)。
 
Input
输入首先是一个整数N,代表测试实例的个数。 然后包括N行数据,每行包括26个<=20的整数x1,x2,.....x26.
 
Output
对于每个测试实例,请输出能找到的总价值<=50的单词数,每个实例的输出占一行。
 
Sample Input
2 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 2 6 2 10 2 2 5 6 1 0 2 7 0 2 2 7 5 10 6 10 2 10 6 1 9
 
Sample Output
7 379297
 
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
#define N 54

int c1[N],c2[N];
int a[N];

int main()
{
    int i,j,k,sum,T;
    scanf("%d",&T);
    while(T--)
    {
        sum=0;
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        for(i=1;i<=26;i++)
        {
            scanf("%d",&a[i]);
        }
        for(i=0;i<=a[1] && i<=50;i++) c1[i]=1;
        for(i=2;i<=26;i++)
        {
            for(j=0;j<=50;j++)
                for(k=0;k<=a[i]*i && (k+j<=50);k+=i)
                    c2[k+j]+=c1[j];
            for(j=0;j<=50;j++)
            {
                c1[j]=c2[j];
                c2[j]=0;
            }
        }
        for(j=1;j<=50;j++)
        {
            sum+=c1[j];
        }
        printf("%d
",sum);
    }
    return 0;
}
趁着还有梦想、将AC进行到底~~~by 452181625
原文地址:https://www.cnblogs.com/hate13/p/4165146.html