有1克、2克、3克、4克的砝码各一枚,能称出哪几种重量?

暴力解

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
  int n;
  int a[100], vis[10000];//vis数组用来判断称过的重量是否出现过
  cin >> n;
  for (int i = 0; i<n; i++)
  {
    scanf("%d", &a[i]);
  }
  memset(vis, 0, sizeof(vis));
  int cnt = 0;
  for (int i = 1; i <= n; i++)//控制使用砝码的数量
  {
    for (int j = 0; j<n; j++)//控制取到的第一个砝码
    {
      int sum = 0;
      for (int k = j; (k<(j + i))&&k<n; k++)//控制取砝码的区间长度
      {
        sum = sum + a[k];
        if (vis[sum] == 0)
        {
          vis[a[k]] = 1;
          cnt++;
        }
      }
    }

  }
  cout << cnt+1 << endl;//最后要加上称的总重量为0的情况
  return 0;
}

母函数解

https://blog.csdn.net/valieli/article/details/53049939

//计算(1+x)*(1+x^2)*(1+x^3)*(1+x^4)
#include <iostream>
 
using namespace std;
#define maxn 20 //数组的大小
int c1[maxn],c2[maxn];//c2为临时存储数组
 
int main()
{
       int m;
       for(int i=0;i<maxn;i++) //初始化第一个式子:(1+x^2+x^3+...)
       {
           c1[i]=1;
           c2[i]=0;
       }
       //以下两个循环的表示过程就是1*(1+x)
       //(1+x^1)(1+x^2)
       //(1+x^1+x^2)*(1+x^3)
       //(1+x^1+x^2+x^3)*(1+x^4)
       //(1+x^1+x^2……x^j)(1+x^i)
       //被乘数*乘数
       //k表示被乘数中的每一项
       for(int i=2;i<=4;i++) // i 从第二个式子循环到第四个。
       {//(1+x)*(1+x^2)*(1+x^3)*(1+x^4)因为(1+x)的系数和指数已经初始化,所以将(1+x)作为乘数,(1+x^2)、(1+x^3)、(1+x^4)依次作为被乘数
           for(int j=0;j<=0.5*i*(i-1);j++) // j 从0循环到它所在式子中的指数最大值,即(1+x^1+x^2+……x^j) 
           {
               for(int k=0,t=0;t<=1;t++,k+=i) //本例子中 k 表示指数增量,t 表示 k 增加几次。本式子中k增加1次
               {
                   c2[k+j]+=c1[j];
               }
           }
           for(int j=0;j<maxn;j++) //更新数组
           {
               c1[j]=c2[j];
               c2[j]=0;
           }
       }
       int sum=0;
       for(int i=0;i<maxn;i++)
        sum=sum+c1[i];
       cout<<sum<<endl;
        
 
   return 0;
}

 

#include <iostream>
#include <cstring>
using namespace std;
#define min(a,b) ((a)<(b)?(a):(b))
int T, N, K, n[8], v[8], a[42], b[42], i, j, k, last, last2;//用一个last变量记录目前最大的指数
int main()
{
    cin >> K >> N;
    for (i = 0; i<K; i++)
        cin >> v[i] >> n[i];//v[i]是存储不同课程的学分值,n[i]是储存每个学分对几个课程(每个学分可以使用的次数)
    a[0] = 1;
    last = 0;
    for (i = 0; i<K; i++)
    {
        last2 = min(last + n[i] * v[i], N);//计算下一个last
        memset(b, 0, sizeof(int)*(last2 + 1));
        for (j = 0; j <= n[i] && j*v[i] <= last2; j++)
            for (k = 0; k <= last && k + j * v[i] <= last2; k++)
                b[k + j * v[i]] += a[k];
        memcpy(a, b, sizeof(int)*(last2 + 1));
        last = last2;
    }
    int sum = 0;
    for (int i = 0; i <= N; i++)
        sum = sum + a[i];
    cout << sum << endl;
    return 0;
}

 

posted @ 2018-11-05 21:10  知道了呀~  阅读(1595)  评论(0编辑  收藏  举报