nbut [1413] Weight 母函数 n个砝码 能称出的重量的个数

  • [1413] Weight

  • 时间限制: 1000 ms 内存限制: 65535 K
  • 问题描述
  • 有n个砝码,每个砝码都有各自的重量。
    那么这些砝码一共能称出哪些重量。
  • 输入
  • 输入一个正整数 n (1 <= n <= 100)表示一共有 n 个砝码。
    接下来一行有n个正整数,每个正整数表示该砝码的重量,其重量不会超过100。
  • 输出
  • 从小到大输出所有可能的情况。
    对于每行,包含两个数,前面一个数是能称出的重量,后面一个数是能称出该重量的不同情况的数量(就算重量相等的砝码也被视为不同的砝码)。
    其数量要对100000007求余。
  • 样例输入
  • 4
    1 2 3 4
    
  • 样例输出
  • 1 1
    2 1
    3 2
    4 2
    5 2
    6 2
    7 2
    8 1
    9 1
    10 1
    
  • 提示
  • 来源
  • Hungar


思路 :很明显是母函数


#include<stdio.h>
#include<string.h>
int num[111],val[111];
int c1[10000+100],c2[10000+100];
#define mod 100000007;
int main()
{
	int n,i,j,k,sum;
	while(scanf("%d",&n)!=EOF)
	{
		sum=0;
		memset(num,0,sizeof(num));
		for(i=1;i<=n;i++)
		{
			scanf("%d",&val[i]);
			num[val[i]]=1;
			sum+=val[i];
		}
			memset(c1,0,sizeof(c1));
			memset(c2,0,sizeof(c2));
			for(j=0;j<=val[1]*num[val[1]];j+=val[1])//限制了每种的个数 最多为 num[val[i]]*val[i]     由于本题都是1 可以去掉不写  
				/*如 质量为1 的砝码有4个  则母函数第一个式子为为 1+x^1+x^2+x^3+x^4*/
				c1[j]=1;
			for(i=2;i<=n;i++)
			{
				for(j=0;j<=sum;j++)//指向上一次已经计算过的式子的项
					for(k=0;k+j<=sum&&k<=num[val[i]]*val[i];k+=val[i])//限制了每种的个数就要这样写了
					{//k指向当前要成的式子的项
						c2[k+j]+=c1[j]%mod;
						c2[k+j]%=mod;
					}
					for(k=0;k<=sum;k++)
					{
						c1[k]=c2[k]%mod;
						c2[k]=0;
					}
			}
			for(i=1;i<=sum;i++)
				if(c1[i])  
				printf("%d %d\n",i,c1[i]);
	}
	return 0;
	
}


下面的是官方的解题报告 :

A.Weight

由题可知,砝码数量不超过100,每个砝码的重量不超过100,那么总重不会超过10000.
我们可以申请一个数组a,a[i]表示组成重量i的数量
那么对于每个砝码,我们都对a数组遍历一遍,
当a[i]是真值时,那么a[i+当前砝码的重量]+=a[i](不要忘了求余),
所以要从尾部开始遍历,不能从头部开始遍历。

但是我们可以剪枝一下,每次都是从10000开始遍历到0有点漫长。
所以我们可以定义一个数all = 0;
all存的是当前砝码以及该砝码之前的所有砝码的总和重量,所以每次只要从all开始遍历到0即可。


   


#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
 
#define mod 100000007
#define N 110
#define M 10005
 
int a[M];
 
int main()
{
    int n;
     
    while (~scanf("%d", &n))
    {
        int all = 0;
        memset(a, 0, sizeof(a));
        a[0] = 1;
        for (int i = 0; i < n; i++)
        {
            int x;
            scanf("%d", &x);
            all += x;
            for (int j = all; j >= 0; j--)
            {
                if (a[j]) a[j + x] = (a[j + x] + a[j]) % mod;
            }
        }
        for (int i = 1; i <= all; i++)
        {
            if (a[i]) printf("%d %d\n", i, a[i]);
        }
    }
     
    return 0;
}


你可能感兴趣的:(nbut [1413] Weight 母函数 n个砝码 能称出的重量的个数)