母函数 初步刷题

来源:互联网 发布:临沂拓普网络拖欠工资 编辑:程序博客网 时间:2024/06/05 13:26

Ignatius and the Princess III

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



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
41020
 
Sample Output
542627
 水题,直接套模板。
#include <iostream>#include <cstdio>#include <cstring>using namespace std;int c1[125], c2[125];int main(){    int n;    while(~scanf("%d", &n)) {        for(int i = 0; i <= n; i++) {            c1[i] = 1;            c2[i] = 0;        }        for(int i = 2; i <= n; i++) {            for(int j = 0; j <= n; j++) {                for(int k = 0; k + j <= n; k += i) {                    c2[k+j] += c1[j];                }            }            for(int j = 0; j <= n ; j++) {                c1[j] = c2[j];                c2[j] = 0;            }        }        printf("%d\n", c1[n]);    }    return 0;}

Square Coins

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



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
210300
 
Sample Output
1427
 
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;int c1[320], c2[320];// 每个表达式指数变为方数,模板改一下就可以 int main(){    int n;    while(~scanf("%d", &n) && n) {        for(int i = 0; i <= n; i++) {            c1[i] = 1;            c2[i] = 0;        }        int t;        for(int i = 2; i*i <= n; i++) {            for(int j = 0; j <= n; j++) {                for(int k = 0; k + j <= n; k += i*i)                    c2[k + j] += c1[j];            }            for(int j = 0; j <= n; j++) {                c1[j] = c2[j];                c2[j] = 0;            }        }        printf("%d\n", c1[n]);    }    return 0;}

Holding Bin-Laden Captive!

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



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 30 0 0
 
Sample Output
4
 
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;int num[3];int c1[10500], c2[10500];int val[3] = {1, 2, 5};int main(){    while(1) {        for(int i = 0; i < 3; i++)            scanf("%d", &num[i]);        int sum = num[0] + 2*num[1] + 5*num[2];        if(sum == 0) break;        memset(c1, 0, sizeof(c1));        memset(c2, 0, sizeof(c2));        for(int i = 0; i <= num[0]; i += val[0]) // 第一个表达式系数初始化            c1[i] = 1;        // 指数和增量有所改变,照样贴模板        for(int i = 1; i <= 2; i++) {            for(int j = 0; j <= sum; j++) {                for(int k = 0; k <= num[i]*val[i] && k+j <= sum; k += val[i])                    c2[k+j] += c1[j];            }            for(int j = 0; j <= sum; j++) {                c1[j] = c2[j];                c2[j] = 0;            }        }        for(int i = 0; i <= sum + 1; i++)            if(c1[i] == 0) {                printf("%d\n", i);                break;            }    }    return 0;}

The Balance

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7815    Accepted Submission(s): 3244


Problem Description
Now you are asked to measure a dose of medicine with a balance and a number of weights. Certainly it is not always achievable. So you should find out the qualities which cannot be measured from the range [1,S]. S is the total quality of all the weights.
 

Input
The input consists of multiple test cases, and each case begins with a single positive integer N (1<=N<=100) on a line by itself indicating the number of weights you have. Followed by N integers Ai (1<=i<=N), indicating the quality of each weight where 1<=Ai<=100.
 

Output
For each input set, you should first print a line specifying the number of qualities which cannot be measured. Then print another line which consists all the irrealizable qualities if the number is not zero.
 

Sample Input
31 2 439 2 1
 

Sample Output
024 5
 
典型的给砝码求能称出的重量种数,因为天平两边都能放所以记得指数加一个两砝码相减的绝对值!
#include <iostream>#include <cstdio>#include<cstring>#include <algorithm>#include <cstdlib>using namespace std;int c1[10000 + 50];int c2[10000 + 50];int num[105], ans[105];int main(){    int n;    while(~scanf("%d", &n)) {        int sum = 0;        for(int i = 1; i <= n; i++) {            scanf("%d", &num[i]);            sum += num[i];        }        memset(c1, 0, sizeof(c1));        memset(c2, 0, sizeof(c2));        int now = num[1];        c1[0] = c1[now] = 1; // 对于每块砝码只有取或不取两种情况        for(int i = 2; i <= n; i++) {            for(int j = 0; j <= now; j++) { // now记录表达式中变量个数                for(int k = 0; k <= num[i]; k += num[i]) { //                    c2[k+j] += c1[j];                    c2[abs(k-j)] += c1[j];                }            }            now += num[i];            for(int j = 0; j <= sum; j++) {                c1[j] = c2[j];                c2[j] = 0;            }        }        int cnt = 0;//        for(int i = 0; i <= sum; i++)//            printf("c1[%d] = %d\n", i, c1[i]);        for(int i = 1; i <= sum; i++) {            if(!c1[i]) {                ans[cnt++] = i;            }        }        sort(ans, ans + cnt);        printf("%d\n", cnt);        for(int i = 0; i < cnt; i++)            printf("%d%c", ans[i], (i != cnt-1) ? ' ' : '\n');    }    return 0;}


 

Coin Change

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 19144    Accepted Submission(s): 6680


Problem Description
Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 1-cent. We want to make changes with these coins for a given amount of money.

For example, if we have 11 cents, then we can make changes with one 10-cent coin and one 1-cent coin, or two 5-cent coins and one 1-cent coin, or one 5-cent coin and six 1-cent coins, or eleven 1-cent coins. So there are four ways of making changes for 11 cents with the above coins. Note that we count that there is one way of making change for zero cent.

Write a program to find the total number of different ways of making changes for any amount of money in cents. Your program should be able to handle up to 100 coins.
 

Input
The input file contains any number of lines, each one consisting of a number ( ≤250 ) for the amount of money in cents.
 

Output
For each input line, output a line containing the number of different ways of making changes with the above 5 types of coins.
 

Sample Input
1126
 

Sample Output
413
 
给硬币价值,问某个价值能被这些硬币以多少形式换出,想用母函数但发现数量没限制难操作,用百钱买百鸡的方法直接暴力。。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cstdlib>using namespace std;int c1[255], c2[2555];int val[5] = {1, 5, 10, 25, 50};int ans;int main(){    int n;    while(~scanf("%d", &n)) {        ans = 0;        for(int i = 0; i <= n; i++) {            for(int j = 0; j*5 <= n-i; j++) {                for(int k = 0; k*10 <= n-i-j*5; k++) {                    for(int t = 0; t*25 <= n-i-j*5-k*10; t++) {                        int m = n-i-j*5-k*10-t*25;                        if(m%50 == 0 && i+j+k+t+m/50 <= 100)                            ans++;                    }                }            }        }        printf("%d\n", ans);    }    return 0;}

Fruit

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4584    Accepted Submission(s): 2654



Problem Description
转眼到了收获的季节,由于有TT的专业指导,Lele获得了大丰收。特别是水果,Lele一共种了N种水果,有苹果,梨子,香蕉,西瓜……不但味道好吃,样子更是好看。

于是,很多人们慕名而来,找Lele买水果。

甚至连大名鼎鼎的HDU ACM总教头 lcy 也来了。lcy抛出一打百元大钞,"我要买由M个水果组成的水果拼盘,不过我有个小小的要求,对于每种水果,个数上我有限制,既不能少于某个特定值,也不能大于某个特定值。而且我不要两份一样的拼盘。你随意搭配,你能组出多少种不同的方案,我就买多少份!"

现在就请你帮帮Lele,帮他算一算到底能够卖出多少份水果拼盘给lcy了。

注意,水果是以个为基本单位,不能够再分。对于两种方案,如果各种水果的数目都相同,则认为这两种方案是相同的。

最终Lele拿了这笔钱,又可以继续他的学业了~
 

Input
本题目包含多组测试,请处理到文件结束(EOF)。
每组测试第一行包括两个正整数N和M(含义见题目描述,0<N,M<=100)
接下来有N行水果的信息,每行两个整数A,B(0<=A<=B<=100),表示至少要买该水果A个,至多只能买该水果B个。
 

Output
对于每组测试,在一行里输出总共能够卖的方案数。
题目数据保证这个答案小于10^9
 

Sample Input
2 31 21 23 50 30 30 3
 

Sample Output
212
 
数量有上下限。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cstdlib>using namespace std;int c1[105], c2[105];int minn[105], maxx[105];int main(){    int n, m;    while(~scanf("%d%d", &n, &m)) {        for(int i = 1; i <= n; i++) {            scanf("%d%d", &minn[i], &maxx[i]);        }        memset(c1, 0, sizeof(c1));        memset(c1, 0, sizeof(c2));        for(int i = minn[1]; i <= maxx[1]; i++)            c1[i] = 1;        for(int i = 2; i <= n; i++) {            for(int j = 0; j <= m; j++) {                for(int k = minn[i]; k <= maxx[i] && k+j <= m; k++) {                    c2[k+j] += c1[j];                }            }            for(int j = 0; j <= m; j++) {                c1[j] = c2[j];                c2[j] = 0;            }        }        printf("%d\n", c1[m]);    }    return 0;}

刷了这么多只能说都是套路。。




0 0