母函数简单应用小结

今天跟着伟峰大佬补基础,做到一题母函数的题。感觉贼刺激。
学习可以百度一下母函数有个博客讲的挺详细的里面还有模板。
然后拉了套kuangbin的母函数,感觉里面的题目大同小异。

A - Square Coins HDU - 1398
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

题意:让你用平方数取组成给的n有几种组成方法。
思路:典型的母函数让你求给定数字的组成个数。幂次为你能够组成的数字,对应的系数为组成该幂次的方案数。

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<vector>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<map>
using namespace std;

//thanks to pyf ...
//thanks to qhl ...

#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
typedef pair<int,int> PII;
typedef long long ll;

const int N = 1e5+5;

int c1[N];
int c2[N];
int Max_N = 17;
int Max_M = 310;
void f()
{
    for(int i = 0; i <= Max_M;i++)
        c1[i] = 1,c2[i] = 0;
    for(int i = 2 ; i <=  Max_N;i++)
    {
        for(int j = 0; j <= Max_M; j++)
        {
            for(int k=0;k<=Max_M;k+=pow(i,2))
            {
                if(j+k <= Max_M);
                    c2[j+k] += c1[j];
            }
        }
        for(int j=0;j<=Max_M;j++)
            c1[j] = c2[j],c2[j] = 0;
    }
}
int main()
{
    int n;
    f();
    while(cin >> n && n)
    {
        cout << c1[n] << endl;
    }
}

B - Holding Bin-Laden Captive! HDU - 1085
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

题意:用给定张数的一块两块五块钱问你最小的不能组成的数是多少。
思路:那么对每个情况来说如果他的系数为0那么就说明没有组成他的方案就是无法组成。从1开始遍历找到第一个系数为0的情况

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<vector>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<map>
using namespace std;

//thanks to pyf ...
//thanks to qhl ...

#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
typedef pair<int,int> PII;
typedef long long ll;

const int N = 1e5+5;

int v[3] = {1,2,5};
int cnt[3];
int c1[N];
int c2[N];
int main()
{
    while(cin >> cnt[0] >> cnt[1] >> cnt[2] && (cnt[0] || cnt[1] || cnt[2]))
    {
        CLR(c1,0);
        CLR(c2,0);
        int sum = 0;
        for(int i=0;i<3;i++)
            sum += cnt[i] * v[i];
        for(int i = 0;i<=cnt[0]*v[0];i++)
            c1[i] = 1, c2[i] = 0;
        for(int i= 1;i<3;i++)
        {
            for(int j=0;j<=sum;j++)
            {
                for(int k = 0;k<=cnt[i]*v[i];k+=v[i])
                {
                    c2[j+k] += c1[j];
                }
            }
            for(int j=0;j<=sum;j++)
                c1[j] = c2[j] , c2[j] = 0;
        }
        int ans = 0;
        for(ans = 0 ;ans <= sum ;ans ++)
            if(c1[ans]==0)
                break;
        cout << ans << endl;
    }
}

C - Big Event in HDU HDU - 1171

 Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don't know that Computer College had ever been split into Computer College and Software College in 2002.
    The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0<N<1000) kinds of facilities (different value, different kinds).
Input
    Input contains multiple test cases. Each test case starts with a number N (0 < N <= 50 -- the total number of different facilities). The next N lines contain an integer V (0<V<=50 --value of facility) and an integer M (0<M<=100 --corresponding number of the facilities) each. You can assume that all V are different.
    A test case starting with a negative integer terminates input and this test case is not to be processed.
Output
    For each case, print one line containing two integers A and B which denote the value of Computer College and Software College will get respectively. A and B should be as equal as possible. At the same time, you should guarantee that A is not less than B.
Sample Input

    2
    10 1
    20 1
    3
    10 1 
    20 2
    30 1
    -1

Sample Output

    20 10
    40 40

&&&&这题最坑的是n<=-1&&&&

题意:给你一种物品的数量和价值,让你将它们尽量均分成两份,求每份的价值和。
思路:本来是一道背包的经典题,以总和的一半为背包容量,做一次多重背包就可以了。那么用母函数的思想同样去求1-m/2之间最小系数为0的幂次,那么就可以做了。坑点如上。。。

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<vector>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<map>
using namespace std;

//thanks to pyf ...
//thanks to qhl ...

#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
typedef pair<int,int> PII;
typedef long long ll;

const int N = 50*50*1000+100;

int cnt[1005];
int v[1005];
int c1[N];
int c2[N];

int main()
{
    int n;
    while(cin >> n)
    {
        if(n<=-1)
            break;
        int sum  = 0;
        for(int i=0;i<n;i++)
            cin >> v[i] >> cnt[i];
        for(int i=0;i<n;i++)
            sum += v[i]*cnt[i];
        CLR(c1,0);
        CLR(c2,0);
//      for(int i=0;i<=cnt[0]*v[0];i+=v[0])
//          c1[i] = 1,c2[i] = 0;
        c1[0] = 1;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<=sum/2;j++)
            {
                for(int k = 0 ;k<=cnt[i]*v[i];k+=v[i])
                {
                    if(j+k <= sum/2&&(c2[j+k]||c1[j]))
                        c2[j+k] = 1;
                }
            }
            for(int j=0;j<=sum/2;j++)
                c1[j] = c2[j] ,c2[j] = 0;
        }   
        int ans ;       
        for(ans=sum/2;ans>=0;ans--)
            if(c1[ans])
                break;
        cout << sum-ans << " " << ans << endl;  
    }
    return 0;
}

D - Ignatius and the Princess III HDU - 1028
“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=a1+a2+a3+…+am;
ai

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

最后这题其实是跟着伟峰大佬做的这题。看到最后其实是最简单的,但是除了母函数的模型以外,还可以直接用记忆化搜索加上递归整数分割的思想。递归整数分割相当于有n个空盘子,把n个苹果可以空的放置到n个盘子里,盘子和苹果均相同。代码如下,两种方法都有。注释的是递归方法,没有注释的是母函数

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<vector>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<map>
using namespace std;

//thanks to pyf ...
//thanks to qhl ...

#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
typedef pair<int,int> PII;
typedef long long ll;

const int N = 1e5+5;
//
//int dp[200][200];
//
//int dfs(int n,int m) // he wei n chaishu
//{
//  if(dp[n][m])
//      return dp[n][m];
//  if(n==0||n==1||m==0||m==1)
//      return dp[n][m] = 1;
//  if(n < m)
//      return dp[n][m] = dfs(n,n);
//  else
//      return dp[n][m] = (dfs(n,m-1)+dfs(n-m,m));
//}
//
//void f()
//{
//  CLR(dp,0);
//  for(int i=1;i<=120;i++)
//  {
//      dfs(i,i);
//  }
//}
//int main()
//{
//  int n;
//  f();
//  while(cin >> n)
//  {
//      cout << dp[n][n] << endl;
//  }
//}
int c1[N];
int c2[N];

int main()
{
    int n;
    while(cin >> n)
    {
        CLR(c1,0);
        CLR(c2,0);
        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<=n;k+=i)
                {
                    c2[k+j] += c1[j];   
                }   
            }   
            for(int j = 0;j<=n;j++)
                c1[j] = c2[j] , c2[j] = 0;
        }   
        cout << c1[n] << endl;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习是一种人工智能(AI)的子领域,致力于研究如何利用数据和算法让计算机系统具备学习能力,从而能够自动地完成特定任务或者改进自身性能。机器学习的核心思想是让计算机系统通过学习数据中的模式和规律来实现目标,而不需要显式地编程。 机器学习应用非常广泛,包括但不限于以下领域: 图像识别和计算机视觉: 机器学习在图像识别、目标检测、人脸识别、图像分割等方面有着广泛的应用。例如,通过深度学习技术,可以训练神经网络来识别图像中的对象、人脸或者场景,用于智能监控、自动驾驶、医学影像分析等领域。 自然语言处理: 机器学习在自然语言处理领域有着重要的应用,包括文本分类、情感分析、机器翻译、语音识别等。例如,通过深度学习模型,可以训练神经网络来理解和生成自然语言,用于智能客服、智能助手、机器翻译等场景。 推荐系统: 推荐系统利用机器学习算法分析用户的行为和偏好,为用户推荐个性化的产品或服务。例如,电商网站可以利用机器学习算法分析用户的购买历史和浏览行为,向用户推荐感兴趣的商品。 预测和预测分析: 机器学习可以用于预测未来事件的发生概率或者趋势。例如,金融领域可以利用机器学习算法进行股票价格预测、信用评分、欺诈检测等。 医疗诊断和生物信息学: 机器学习在医疗诊断、药物研发、基因组学等领域有着重要的应用。例如,可以利用机器学习算法分析医学影像数据进行疾病诊断,或者利用机器学习算法分析基因数据进行疾病风险预测。 智能交通和物联网: 机器学习可以应用于智能交通系统、智能城市管理和物联网等领域。例如,可以利用机器学习算法分析交通数据优化交通流量,或者利用机器学习算法分析传感器数据监测设备状态。 以上仅是机器学习应用的一部分,随着机器学习技术的不断发展和应用场景的不断拓展,机器学习在各个领域都有着重要的应用价值,并且正在改变我们的生活和工作方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值