A Famous Stone Collector

Problem Description
Mr. B loves to play with colorful stones. There are n colors of stones in his collection. Two stones with the same color are indistinguishable. Mr. B would like to 

select some stones and arrange them in line to form a beautiful pattern. After several arrangements he finds it very hard for him to enumerate all the patterns. So he asks you to write a program to count the number of different possible patterns. Two patterns
are considered different, if and only if they have different number of stones or have different colors on at least one position.
 
Input
Each test case starts with a line containing an integer n indicating the kinds of stones Mr. B have. Following this is a line containing n integers - the number of 

available stones of each color respectively. All the input numbers will be nonnegative and no more than 100.
 
Output
For each test case, display a single line containing the case number and the number of different patterns Mr. B can make with these stones, modulo 1,000,000,007, 

which is a prime number.
 
Sample Input
3
1 1 1
2
1 2
 
Sample Output
Case 1: 15
Case 2: 8
Hint
In the first case, suppose the colors of the stones Mr. B has are B, G and M, the different patterns Mr. B can form are: B; G; M; BG; BM; GM; GB; MB; MG;
BGM; BMG; GBM; GMB; MBG; MGB.
 
Source

题意为:

有n种颜色的石头,每种颜色有num[i]块,每种颜色的石头是不可区分的,在这么多石头里面挑选石头来排成一条线,问一共同拥有多少种排法。线的长度为(1到  num[i]+num[2]+num[3]+.....num[n]。

比方有三种颜色石头,B,G,M,表示颜色。每种颜色一块石头,那么可能的序列有 B; G; M; BG; BM; GM; GB; MB; MG; BGM; BMG; GBM; GMB; MBG; MGB

用dp[i][j]代表用前i种颜色的石头去排成长度为j的序列

那么有那种情况:

①第i种颜色的石头不使用,那么 dp[i][j] = dp[i-1][j];

②第i种颜色的石头使用(序列可到达长度为原来的长度加上第i种颜色的个数),有num[i]个。原来的石头序列中去掉k个,从第i种颜色石头中取出k个。这里(k<=j),插入到原来的序列中,一共同拥有j个位置,从中挑选k个就能够了(不是单纯的插空。能够理解为,要构成长度j的序列,有j个位置,首先让第i种颜色的k个石头去挑k个位置。这就包含了相邻和不相邻的情况,因为同样颜色不可区分,有
c[j][k]种方法,然后再让剩下的石头序列依照原来的顺序依次填入每一个空位置就能够了).

有dp[i][j]+=dp[i-1][j-k]*c[j][k];

代码:

#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long ll;
const int maxn=110;//种类数最大
const int mod=1000000007;
ll dp[maxn][maxn*maxn];//代表用前i种颜色组成长度为j的序列的方法数
ll c[maxn*maxn][maxn];//从当前序列长度+1种中选出j种。j不会超过maxn
int n;//n种颜色
int num[maxn];//每种颜色有多少石头
int sum;//最长的序列长度 void getC()
{
c[0][0]=c[1][0]=c[1][1]=1;
for(int i=2;i<maxn*maxn-1;i++)
{
c[i][0]=1;
for(int j=1;j<maxn-1;j++)
{
if(i==j)
c[i][j]=1;
else
{
c[i][j]=c[i-1][j]+c[i-1][j-1];
c[i][j]%=mod;
}
}
}
} int DP()
{
memset(dp,0,sizeof(dp));//一定的初始化为0。后面dp[i][j]=dp[i-1][j]用到了..
for(int i=1;i<=n;i++)
dp[i][0]=1;
for(int i=1;i<=num[1];i++)
dp[1][i]=1;
int tsum=num[1];
for(int i=2;i<=n;i++)//一共同拥有N种
{
tsum+=num[i];//前i种颜色的总长度,最多的
for(int j=1;j<=tsum;j++)
{
dp[i][j]=dp[i-1][j];//对于当前长度j,一种情况是不用第i种颜色的石头
for(int k=1;k<=num[i]&&k<=j;k++)//使用当前颜色石头,可是要去掉一定的长度,使用新的颜色石头来填充
{
dp[i][j]+=dp[i-1][j-k]*c[j][k];//为什么是 c[j][k]呢,能够这样理解。一共同拥有J个位置。让第i中颜色的求先去选当中k个位置。然后剩下的位置让原来颜色的顺序放下就好了
dp[i][j]%=mod;
}
}
}
ll ans=0;
for(int i=1;i<=sum;i++)
{
ans+=dp[n][i];
ans%=mod;
}
return ans;
} int main()
{
getC();
int cas=1;
while(cin>>n)
{
sum=0;
for(int i=1;i<=n;i++)
{
cin>>num[i];
sum+=num[i];
}
cout<<"Case "<<cas++<<": "<<DP()<<endl;
}
return 0;
}

[ACM] hdu 4248 A Famous Stone Collector (DP+组合)的更多相关文章

  1. HDU 4248 A Famous Stone Collector 组合数学dp ****

    A Famous Stone Collector Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  2. HDOJ 4248 A Famous Stone Collector DP

    DP: dp[i][j]前i堆放j序列长度有多少行法, dp[i][j]=dp[i-1][j] (不用第i堆), dp[i][j]+=dp[i-1][j-k]*C[j][k] (用第i堆的k个石头) ...

  3. hdu 4248 A Famous Stone Collector

    首先发现一个很头痛的问题,下面是2个求排列组合的代码 memset(C,,sizeof(C)); ;i<;i++) { C[i][]=; ;j<=;j++) C[i][j]=(C[i-][ ...

  4. HDU 4294 A Famous Equation(DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4249 题目大意:给一个a+b=c的表达式,但是a.b.c中部分位的数字丢失,并用?代替,问有多少种方案 ...

  5. ACM: HDU 1028 Working out 解题报告-DP

    Working out time limit per test  2 seconds memory limit per test  256 megabytes input  standard inpu ...

  6. [ACM] HDU 1227 Fast Food (经典Dp)

    Fast Food Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  7. ACM HDU Bone Collector 01背包

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 这是做的第一道01背包的题目.题目的大意是有n个物品,体积为v的背包.不断的放入物品,当然物品有 ...

  8. HDOJ(HDU).2602 Bone Collector (DP 01背包)

    HDOJ(HDU).2602 Bone Collector (DP 01背包) 题意分析 01背包的裸题 #include <iostream> #include <cstdio&g ...

  9. HDU 2227 Find the nondecreasing subsequences (DP+树状数组+离散化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227 Find the nondecreasing subsequences             ...

随机推荐

  1. Android 中模仿 Twitter 实现 Toolbar Indicator

    项目地址:https://github.com/nekocode/ToolbarIndicator

  2. Libvirt中windows虚拟机的动态内存管理

    非常短的前提 Libvirt支持对虚拟机进行内存动态扩展,可是windows虚拟机首先须要安装virtio-win驱动. KVM提供的virtio-win驱动下载地址: http://www.linu ...

  3. RedHat6.5 安装OpenStack all in one-RDO方式

    OpenStack是一个开源的云平台.由各个组件协同工作,安装非常复杂. RedHat有个关于Openstack的项目RDO,能够简化安装过程,可是假设真按RDO所说的三步去安装,发现安装过程中还是有 ...

  4. Hadoop解析--MapReduce

    从本篇博客開始咱们一起来具体了解Hadoop的每一个部分.我们在上篇博客中介绍了HDFS,MapReduce,MapReduce为了更有效率事实上是建立在HDFS之上的.有了分布式的文件系统,我们就能 ...

  5. 【React Native开发】React Native控件之ProgressBarAndroid进度条解说(12)

    ),React Native技术交流4群(458982758).请不要反复加群! 欢迎各位大牛,React Native技术爱好者增加交流!同一时候博客左側欢迎微信扫描关注订阅号,移动技术干货,精彩文 ...

  6. CoreData 从入门到精通 (一) 数据模型 + CoreData 栈的创建

    CoreData 是 Cocoa 平台上用来管理模型层数据和数据持久化的一个框架,说简单点,就是一个数据库存储框架.CoreData 里相关的概念比较多,而且初始化也非常繁琐,所以对初学者的学习还是有 ...

  7. hexo博客谷歌百度收录踩坑日记

    title: hexo博客谷歌百度收录踩坑日记 toc: false date: 2018-04-17 00:09:38 百度收录文件验证 无论怎么把渲染关掉或者render_skip都说我的格式错误 ...

  8. MetaSploit攻击实例讲解------攻击445端口漏洞(kali linux 2016.2(rolling))(详细)

    不多说,直接上干货! 大家,相信最近的这个事件,对于445端口已经是非常的小心了.勒索病毒 445端口是一个毁誉参半的端口,有了它我们可以在局域网中轻松访问各种共享文件夹或共享打印机,但也正是因为有了 ...

  9. calender怎么获取每周的周日(给每周的周日特定时间点设置定时)

    获取每周的周日 //如果是周日,特殊处理.老外的周日-周六为一周 calendarTemp.add(Calendar.WEEK_OF_MONTH,1); calendarTemp.set(Calend ...

  10. navigator.clipboard 浏览器原生剪贴板

    浏览器原生剪贴板 navigator.clipboard 写入 navigator.clipboard.writeText navigator.clipboard.writeText('Linr Te ...