zoukankan      html  css  js  c++  java
  • hdu 4248 A Famous Stone Collector

    首先发现一个很头痛的问题,下面是2个求排列组合的代码

    1  memset(C,0,sizeof(C));
    2     for(int i=0;i<10010;i++)
    3     {
    4         C[i][0]=1;
    5         for(int j=1;j<=100;j++)
    6             C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
    7     }
    1 C[0][0]=1;
    2     for(int i=1;i<10010;i++)
    3         for(int j=0;j<=100;j++)
    4            if(j==0) C[i][j]=C[i-1][j];
    5            else C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;

    其中第一个是刘汝佳上面的代码,不知为什么在杭电OJ上就是WA,第二个就能AC,就路过的大神指点

    题目大意

    给你一些不同颜色的石头,问选出一些石头排成一排总共有多少种不同排法,不同数量的石头视为不同情况,每个位置上的石头颜色都相同视为相同情况。

    分析 

    dp+排列组合

    dp[i][j] 表示前i堆石子构成长度为j的串的方案数;

    状态转移方程是:k为i堆使用的数量

    dp[i][j] = (dp[i][j] + dp[i-1][j-k] * C[j][k]%MOD)%MOD;

    可以这样想

     dp[ i ][ j ] = dp[ i-1 ][ j ]; //未放入第i种颜色的石头

     dp[ i ][ j ] += dp[ i-1 ][ j - k ] * C[ j ][ k ];  //放入k个第i种颜色的石 

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #define MOD 1000000007
     5 using namespace std;
     6 typedef long long LL;
     7 LL C[10010][110];
     8 void get_c()
     9 {
    10     memset(C,0,sizeof(C));
    11     for(int i=0;i<10010;i++)
    12     {
    13         C[i][0]=1;
    14         for(int j=1;j<=100;j++)
    15             C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
    16     }//这一步是错的,不知为啥
    17     
    18     
    19     C[0][0]=1;
    20     for(int i=1;i<10010;i++)
    21         for(int j=0;j<=100;j++)
    22            if(j==0) C[i][j]=C[i-1][j];
    23            else C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
    24 }
    25 LL dp[110][10010];
    26 int main()
    27 {
    28     int cas=0,sum,n,num;
    29     LL ans;
    30     get_c();
    31     while(scanf("%d",&n)!=EOF)
    32     {
    33         memset(dp,0,sizeof(dp));
    34         dp[0][0]=1;
    35         sum=0;
    36         for(int i=1;i<=n;i++)
    37         {
    38             scanf("%d",&num);
    39             sum+=num;
    40             for(int k=0;k<=num;k++)
    41             {
    42                 for(int j=k;j<=sum;j++)
    43                     dp[i][j]=(dp[i][j]+(dp[i-1][j-k]*C[j][k])%MOD)%MOD;
    44             }
    45         }
    46         ans=0;
    47         for(int i=1;i<=sum;i++)
    48             ans=(ans+dp[n][i])%MOD;
    49         printf("Case %d: %I64d
    ",++cas,ans);
    50     }
    51     return 0;
    52 }
  • 相关阅读:
    [Android] 开源框架 xUtils HttpUtils 代理设置 (Temporary Redirect错误)
    [Android] 开源框架 Volley 自定义 Request
    [算法]——汉诺塔的递归深度
    [libwww-perl]——POST方法的使用
    [Go语言]从Docker源码学习Go——Interfaces
    [Linux]可用于管道操作的命令
    npoi 导出word中写入特殊字符
    thinkphp框架中使用PHPExcel,按模板导出excel
    Access导出csv 内容添加双引号 vba
    导出excel和PDF小结 vba
  • 原文地址:https://www.cnblogs.com/tsw123/p/4437155.html
Copyright © 2011-2022 走看看