UVA - 12316 Sewing Buttons with Grandma (有重复元素的组合)

Description

 Sewing Buttons with Grandma 

After so many years of studying math in the Academy of Colombian Mathematics (ACM) in the tropic, Eloi has finally decided to visit his grandmother for the winter in the north hemisphere. ``Buttons and patches and the cold wind
blowing, the days pass quickly when I am sewing‘‘ she says - Eloi now remembers how grandma quilts have love in every stitch. As a matter of fact, he has decided to learn the useful handicraft art of sewing buttons with grandma.

Eloi has realized that there is an interesting mathematical puzzle related to the task of sewing buttons to the front of a shirt. Given a collection of
n1 buttons of color
c1, n2 buttons of color
c2, ..., nk buttons of color
ck, and a shirt with
m front buttonholes, in how many ways the buttonholes can be assigned
m buttons from the n1 +
... + nk buttons?

Input

The input consists of several test cases. The first line of each test case contains two integers
m and k separated by a blank (1

m 50,
1
k 50). Then
k lines follow each containing an integer
ni with 1
ni 50. The last test case is followed by a line containing two zeros.

Output

The output consists of one line per test case containing the number of ways the
m buttonholes can be assigned
m buttons from the n1 +
...
+ nk buttons, assuming that the colors
c1,..., ck are pairwise distinct.

Sample Input

1 3
3
1
1
3 2
4
2
3 2
1
1
0 0

Sample Output

3
7
0

题意:给你m个纽扣位置,然后有n个不同颜色的重复的纽扣,求组合数

思路:先试着假设f[i][j]表示用i个不同颜色的纽扣组成j个的可能数,那么

f[i][j]=∑i=1n∑j=1m∑k=0a[i]f[i?1][j?k]?C[j][k]          
其中 C[j][k]  
表示组合数

式子的意思是在i-1的情况下,从j个中挑出k个来放第i个颜色,所以要乘上组合数

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		final int maxn = 105;
		int a[] = new int[maxn];
		BigInteger f[][] = new BigInteger[maxn][maxn];
		BigInteger c[][] = new BigInteger[maxn][maxn];
		int n, m;
		for (int i = 0; i <= 50; i++) {
			c[i][0] = BigInteger.ONE;
			c[i][i] = BigInteger.ONE;
		}
		for (int i = 2; i <= 50; i++)
			for (int j = 1; j < i; j++)
				c[i][j] = c[i-1][j-1].add(c[i-1][j]);
		Scanner in = new Scanner(System.in);
		while (true) {
			m = in.nextInt();
			n = in.nextInt();
			if (m == 0 && n == 0)
				break;
			for (int i = 1; i <= n; i++)
				a[i] = in.nextInt();
			for (int i = 0; i <= 50; i++)
				for (int j = 0; j <= 50; j++)
					if (j == 0)
						f[i][j] = BigInteger.ONE;
					else f[i][j] = BigInteger.ZERO;
			for (int i = 1; i <= n; i++)
				for (int j = 1; j <= m; j++)
					for (int k = 0; k <= a[i]; k++)
						if (j - k >= 0)
							f[i][j] = f[i][j].add(f[i-1][j-k].multiply(c[j][k]));
			System.out.println(f[n][m]);
		}
	}
}

UVA - 12316 Sewing Buttons with Grandma (有重复元素的组合)

时间: 2024-08-01 08:04:16

UVA - 12316 Sewing Buttons with Grandma (有重复元素的组合)的相关文章

枚举有重复元素的组合

之前有一篇博文有介绍枚举又重复元素的排列,这里先介绍一下怎么正常枚举有重复元素的组合 首先先来一个仅支持不同元素的枚举组合的程序 多年前的知识宝藏 1 #include<cstdio> 2 const int maxn=1005; 3 int n,m,ans; 4 int a[maxn],vi[maxn]; 5 void dfs(int dp) 6 { 7 if(dp>m) 8 { 9 for(int i=1;i<=m;i++) printf("%d",a[i]

从n个元素中选择k个的所有组合(包含重复元素)

LeetCode:Combinations这篇博客中给出了不包含重复元素求组合的5种解法.我们在这些解法的基础上修改以支持包含重复元素的情况.对于这种情况,首先肯定要对数组排序,以下不再强调 修改算法1:按照求包含重复元素集合子集的方法LeetCode:Subsets II算法1的解释,我们知道:若当前处理的元素如果在前面出现过m次,那么只有当前组合中包含m个该元素时,才把当前元素加入组合 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

UVA - 11076 Add Again (重复元素的排列)

Summation of sequence of integersis always a common problem in Computer Science. Rather than computing blindly,some intelligent techniques make the task simpler. Here you have to find thesummation of a sequence of integers. The sequence is an interes

Add Again(重复元素排序)

Add Again Input: Standard Input Output: Standard Output Summation of sequence of integers is always a common problem in Computer Science. Rather than computing blindly, some intelligent techniques make the task simpler. Here you have to find the summ

请写一个算法,用于将list集合内重复元素剔除

package Homework; import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Scanner;/** * list集合是否可以包含重复元素? * 如果可以,请写一个算法,用于将list集合内重复元素剔除. * @author 张致远 * */public class Homework2 { public static void main(String[]

LeetCode:Contains Duplicate - 判断数组内是否有重复元素

1.题目名称 Contains Duplicate(判断数组内是否有重复元素) 2.题目地址 https://leetcode.com/problems/contains-duplicate/ 3.题目内容 英文:Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in

js 去除重复元素

方法一: 1 //数组去重的方法 2 Array.prototype.unique=function(){ 3 //集中声明变量 4 var 5 oldArr=this, 6 newArr=[oldArr[0]], 7 len=oldArr.length, 8 i=1; 9 //过滤空数组 10 if(!len) return this; 11 //过滤重复元素 12 for(;i<len;i++){ 13 newArr.indexOf(oldArr[i])<0 ? newArr.push(_

C语言 &#183; 删除重复元素

算法提高 11-2删除重复元素 时间限制:10.0s   内存限制:256.0MB 问题描述 为库设计新函数DelPack,删除输入字符串中所有的重复元素.不连续的重复元素也要删除. 要求写成函数,函数内部使用指针操作. 样例输入 1223445667889 样例输出 13579 样例输入 else 样例输出 ls 数据规模和约定 字符串数组最大长度为100. 1 /* 2 思路: 3 将字符串存入字符数组a中,设将值拷贝给数组b,遍历b的每个元 4 素,与a中的每个元素比较,有相同则b中对应元

排序及重复元素去重的说明,TreeSet,HashSet

先看下面一段代码: package 类集; import java.util.Set; import java.util.TreeSet; class Person{ private String name ; private int age ; public Person(String name,int age){ this.name = name ; this.age = age ; } public String gtoString(){ return "姓名:" + this.