zoj——1202 Divide and Count

Divide and Count


Time Limit: 2 Seconds      Memory Limit: 65536 KB


Jack has several beautiful diamonds, each of them is unique thus precious. To keep them safe, he wants to divide and store them in different locations. First, he has bought some coffers. These boxes are identical except that their capacities (the number of the diamonds that a box can contain) may diverse. Before he puts his diamonds in, he wants to figure out how many different ways he can store these diamonds into the coffers. He recruits you, a young programmer from Zhejiang University, to give him the answer.

Input:
The input consists of several test cases. Each test case begins with a positive integer N, which indicates the number of the coffers Jack has bought. Then the following N integers are the capacities of each box. The total number of the diamonds Jack has equals to the sum of the capacities of all the coffers.

All the integers given are no greater than 12, you can be assured that a result always fits into a 32-bit integer.

Output:
For every test case, print out an integer representing the number of the different ways Jack can store his diamonds. Each integer is to be printed on a single line.

Sample input:

2
3 3
3
1 2 3

Sample output:

10
60

题意:

杰克有好几颗漂亮的钻石,每一颗都是独一无二的。为了保护他们的安全,他想把它们分开存放在不同的地方。首先,他买了一些小金库。这些盒子是相同的,只是它们的容量(盒子所能容纳的钻石的数目)可能是不同的。在他把钻石放进去之前,他想弄清楚他能把这些钻石存放在金库里有多少种不同的方式。他招募你,一个来自浙江大学的年轻程序员,给他答案。
输入:
输入由几个测试用例组成。每个测试用例以一个正整数n开头,这表示杰克购买的金库的数量。接下来的n个整数是每个盒子的容量。杰克钻石的总数等于所有金库的总和。
给定的所有整数不大于12,可以确保结果总是适合32位整数。
输出:
对于每个测试用例,打印出一个整数,表示杰克存储钻石的不同方式的数量。每个整数都要在一行上打印。

思路:

排列组合

我们来手模一下第一个样例:2    3  3  我们先往第一个金库中装钻石,这样的话我们有C36(比较丑,凑活着看吧)种方案,我们在往第二个匣子中放钻石,这是我们已经把3个钻石放入了第一个匣子中,也就是说我们这是还剩下6-3颗钻石,我们把这些钻石放入这个匣子中,有C33种方案。但是我们这样算出来肯定是不对的,因为容积相同的金库完全相同,那么也就是说我们要除去匣子相同的方案数,但是除什么呢??!这也正是我与一位大佬发生争执的地方。我认为应该是除相同个数的阶乘,而他认为除相同的个数。

好,我们先不看这个样例,因为看不出来啊、、、、

我们自己手模样例,就找个简单的吧,3  1  1  1 我们跟上面说的一样,先往第一个匣子中放钻石,这样我们有C13种方案,我们往第二个匣子中放钻石这是我们有3-1颗钻石,我们找出一个来放入第二个匣子中,这样我们有C12种方案数,最后一个我也就不再写了,这样我们求出来一共有6种方法,但是我们知道这三个匣子是完全相同的,那么也就是说我们只有一种方法,那么这样的话我们该除几就显而易见了。

至于题的这个公式,我想各位大佬上面的解释的时候应该也都能看明白(也可能本蒟蒻写的一点都不明白)那我就不啰嗦了

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 20
using namespace std;
long long ans;
int n,m,w,tot,a[N],num[N];
int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
int jie(int x,int y)
{
    int sum=1;
    for(int i=x;i<=y;i++)
     sum*=i;
    return sum;
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=12;i++)
         a[i]=0;    ans=1;tot=0;
        for(int i=1;i<=n;i++)
         num[i]=read(),a[num[i]]++,tot+=num[i];
        for(int i=1;i<=n;i++)
        {
            w=tot-num[i]+1;
            ans*=jie(w,tot)/jie(1,num[i]);
            tot-=num[i];
        }
        for(int i=1;i<=12;i++)
         if(a[i]) ans=ans/jie(1,a[i]);
        cout<<ans<<endl;
    }
    return 0;
}
时间: 2024-10-13 03:36:05

zoj——1202 Divide and Count的相关文章

zoj题目分类

饮水思源---zoj 转载自:http://bbs.sjtu.edu.cn/bbscon,board,ACMICPC,file,M.1084159773.A.html 注:所有不是太难的题都被归成了“简单题”,等到发现的时候已经太晚了,我太死脑筋 了……:( 有些题的程序我找不到了,555……:( SRbGa的题虽然都很经典……但是由于其中的大部分都是我看了oibh上的解题报告后做 的,所以就不写了…… 题目排列顺序没有规律……:( 按照个人感觉,最短路有的算做了DP,有的算做了图论. 有些比较

POJ百道水题列表

以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight Moves1101 Gamblers1204 Additive equations 1221 Risk1230 Legendary Pokemon1249 Pushing Boxes 1364 Machine Schedule1368 BOAT1406 Jungle Roads1411 Annive

466. Count The Repetitions

Define S = [s,n] as the string S which consists of n connected strings s. For example, ["abc", 3] ="abcabcabc". On the other hand, we define that string s1 can be obtained from string s2 if we can remove some characters from s2 such th

Java实现排序

Java源文件地址:百度云:http://pan.baidu.com/s/1qW6ygzU提取码:dndr 交换函数:    public static void swap(int array[], int x, int y) {        int t = array[x];        array[x] = array[y];        array[y] = t;    } 一.直接插入:    public static void insertSort(int[] array) {

Java的大数操作分为BigInteger和BigDecimal

Java的大数操作分为BigInteger和BigDecimal,但这两给类是分开使用的,有时候在编程的时候显得略微繁琐,现在编写了一个将二者合二为一的大数操作类. 大数操作类代码如下: 1 package blog; 2 3 import java.math.BigDecimal; 4 import java.math.BigInteger; 5 import java.math.RoundingMode; 6 7 /** 8 * 9 * @author 瓦尔登湖畔的小木屋 10 * BigN

利用merge sort寻找逆序对

算法导论第二章 练习题,使用合并排序算法寻找逆序对 基本思想: 在merge过程中,交换位置与一组逆序对是一一对应的. 在左右两个子数组内部是排好序的,所以逆序对的出现仅仅存在于“左数组中的数组大有右数组中的数字”的情况. 所以在每次的merge过程中就可以进行逆序对的计数. java代码实现: 1 public class InversionCount { 2 public static void main(String[] args){ 3 int[] arr = new int[]{2,3

十大排序算法 JAVA代码

冒泡排序 插入排序 选择排序 希尔排序 归并排序 快速排序 堆排序 计数排序 基数排序 桶排序  O是指计算机执行命令所需的时间 nlogn是算法的时间复杂度,一般排序用的是log2n 总体总结表:这个有个错误就是归并排序需要一个o(n)的辅助数组  冒泡排序 主要思想:外层循环从1到n-1,内循环从当前外层的元素的下一个位置开始,依次和外层的元素比较,出现逆序就交换. 特点:stable sort(稳定性排序).In-place sort(不占用额外的空间,只是交换元素) 最优复杂度:当输入数

网易笔试题:找出指定区间数列中能被3整除的个数

题目描述:给定一个数列:1,12,123,...,12345678910,1234567891011...,找出指定区间能被3整除的个数. 输入描述:输入两个数字l和r,代表数列的第l个数和第r个数 输入描述:输出区间内能被三整除的个数 例:输入:2 5 输出:3 因为12,123,1234,12345中能被3整除的有3个. 思路:该题涉及的数字比较大,不能直接用整形或是长整型来存储数字,可以用字符串来存储数字,判定能否被3整除的方法就是看将数字各位的数相加得到的数能否被3整除. 代码如下: #

Java实现发红包模拟

1.先画界面 package com.cmk; import javax.swing.*; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Hash