【HDU 4248】组合数学 A Famous Stone Collector
来源:互联网 发布:php app接口开发步骤 编辑:程序博客网 时间:2024/06/05 09:43
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.
available stones of each color respectively. All the input numbers will be nonnegative and no more than 100.
which is a prime number.
31 1 121 2
Case 1: 15Case 2: 8
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.
题目大意:
有n种不同颜色的石头,每种颜色有ki块,同色石头全都一样,现在将它们选出若干块任意排列,让你求共有多少种不同的排列方式。
既然是组合数学的诈尸二连击,还是应该纪念一下!
这道题初看时我毫无头绪,想起可重复元素的全排列公式:S=n!/(n1!*n2!*...*nm!),可是却没有一个选排列公式,若是枚举用哪些石头,最高可达2^10000种方法,无奈只能放弃这个做法。后来我发现,如果使用类似于动态规划的方法,进行分步计数,或许就没有那么复杂了,递推式也很好想:
设f[i][j]表示用前i种石头摆j个的方法,则f[i][j]=sum(f[i-1][k]*C(j,k)),其中max(j-stone[i],0)≤k≤j,可以发现这是一个三维的,i有100,j有10000,k有100,仔细观察时间限制是15s,这样是完全可以过的。最后输出f[n][i](1≤i≤Σstone[i])即可。其中stone表示第i种石头个数。初始化f[i][0]=1并刷出组合数表。
还是来解释一下状态转移方程式,由于前i种石头摆了j个,那么第i种石头可以摆0~stone[i]个,然后剩下的就是前i-1种石头了。而对于前i-1种石头每一种方案,第i种石头都可以有C(j,k)种方式摆放。为什么是C(j,k)呢?我们把这j块石头看做一个序列OOO...OOO,其中有j-k块是第i种,从这j块石头中选出j-k块放i即可,就是C(j,j-k),也就等于C(j,k)(这样看着清爽...)
所以我就这么写了,结果RE,原因是我的组合数表只打到了C(10000,100),但我写了C(j,k)然后k可以大于100!所以还是写成C(j,j-k)吧555。
你们要的代码:
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;#define MOD 1000000007#define ll long longint n;ll C[10005][105],stone[105],S[105],f[105][10005];int main(){C[0][0]=1;for(int i=1;i<=10000;i++){C[i][0]=1;for(int j=1;j<=i&&j<=100;j++)C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;}for(int cas=1;scanf("%d",&n)==1;cas++){memset(f,0,sizeof(f));for(int i=1;i<=n;i++){scanf("%lld",&stone[i]);S[i]=stone[i]+S[i-1];}f[0][0]=1;for(int i=1;i<=n;i++){f[i][0]=1;for(int j=1;j<=S[i];j++)for(int k=j;k>=0&&k>=j-stone[i];k--)f[i][j]=(f[i][j]+(f[i-1][k]*C[j][j-k])%MOD)%MOD;}ll ans=0;for(int i=1;i<=S[n];i++)ans=(ans+f[n][i])%MOD;printf("Case %d: %lld\n",cas,ans);}}
- hdu 4248 A Famous Stone Collector(组合数学&DP)
- hdu 4248 A Famous Stone Collector dp+组合数学
- 【HDU 4248】组合数学 A Famous Stone Collector
- 【原创】【组合数学】HDU 4248 A Famous Stone Collector
- [ACM] hdu 4248 A Famous Stone Collector (DP+组合)
- HDU 4248 A Famous Stone Collector(组合计数)
- HDU 4248 A Famous Stone Collector(DP + 组合数)
- hdu 4248 A Famous Stone Collector
- hdu 4248 A Famous Stone Collector
- HDU 4248 A Famous Stone Collector (dp)
- HDOJ 题目4284 A Famous Stone Collector(组合数学)
- HDU_4248_A Famous Stone Collector(组合数学+DP)
- HDU 4248 A Famous Stone Collector(类多重背包+组合数)
- Famous Stone Collector HDU
- HDOJ 4248 A Famous Stone Collector DP
- #HDU4248#A Famous Stone Collector(组合数)
- hdu4248 A Famous Stone Collector
- hdu 4248 A Famous Stone Collector【DP】【Fudan Local Programming Contest 2012 D】
- Asp.net DataTable to CSV 文件
- git服务器搭建
- Hdu 2026 首字母变大写
- 数据库优化
- HDOJ 5965 扫雷 【DP】
- 【HDU 4248】组合数学 A Famous Stone Collector
- 学习笔记2017.07.08-day6,am-CSS字体
- C++using声明和using指示
- 算法导论15章 动态规划 dynamic programming 复习第二弹 最长公共子序列
- C++运算符的重载
- mvc mvp mvvm 概说
- java 经典多点面试题
- opencv在编译报错的汇总
- 32位汇编写简单加减乘除计算器