3 1 1 1 2 1 2
Case 1: 15 Case 2: 8HintIn 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种颜色的石头,每种颜色有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+组合),布布扣,bubuko.com
[ACM] hdu 4248 A Famous Stone Collector (DP+组合)
原文:http://blog.csdn.net/sr_19930829/article/details/38300709