• Luogu P1077 摆花


     P1077 摆花

    题目描述

    小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆。通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号。为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列。

    试编程计算,一共有多少种不同的摆花方案。

    输入输出格式

    输入格式:

    第一行包含两个正整数n和m,中间用一个空格隔开。

    第二行有n个整数,每两个整数之间用一个空格隔开,依次表示a1、a2、……an。

    输出格式:

    输出只有一行,一个整数,表示有多少种方案。注意:因为方案数可能很多,请输出方案数对1000007取模的结果。

    输入输出样例

    输入样例#1:
    2 4
    3 2
    
    输出样例#1:
    2

    说明

    【数据范围】

    对于20%数据,有0<n≤8,0<m≤8,0≤ai≤8;

    对于50%数据,有0<n≤20,0<m≤20,0≤ai≤20;

    对于100%数据,有0<n≤100,0<m≤100,0≤ai≤100。

    NOIP 2012 普及组 第三题

      简简单单的一道dp水题,转移方程找半天,我怕不是得退役。

      解1: dp[i][j]表示前i个品种,当摆放了j个花的时候的方案数。

      转移方程dp[i][j] = sum(dp[i-1][j-0],dp[i-1][j-1],…,dp[i-1][j-k]);  // k<=a[i]   想想这里为什么是j-k

      边界条件是dp[1..n][0] = 1;  意思是前i个品种摆放0个花时,方案数只有1.

      接下来是代码:

     1 #include <cstdio>
     2 
     3 int n, m, a[105];
     4 long long dp[105][105];
     5 
     6 
     7 int main()
     8 {
     9     //freopen("1.in", "r", stdin);
    10     //freopen("1.out", "w", stdout);
    11     
    12     scanf("%d%d", &n, &m);
    13     for(int i=1; i<=n; i++)
    14         scanf("%d", &a[i]);
    15     
    16     for(int i=0; i<n; i++)
    17         dp[i][0] = 1;
    18     
    19     for(int i=1; i<=n; i++)
    20         for(int j=1; j<=m; j++)
    21             for(int k=0; k<=a[i] && k<=j; k++)
    22             {
    23                 //k表示当前品种摆放数目
    24                 dp[i][j] += dp[i-1][j-k];
    25                 dp[i][j] %= 1000007;
    26             }
    27     /*
    28     for(int i=0; i<=n; i++)
    29     {
    30         for(int j=0; j<=m; j++)
    31             printf("(%d,%d)%lld ", i, j, dp[i][j]);
    32         printf("
    ");
    33     }*/
    34     printf("%lld", dp[n][m]);
    35     return 0;
    36 }

      解2:dp[i][j]表示前i个品种,还有j个空位的时候的方案数。

      转移方程dp[i][j] = sum(dp[i-1][j+0],dp[i-1][j+1],…,dp[i-1][j+k]);  // k<=a[i]  这里为什么是j+k

      边界条件是dp[1..n][m] = 1;  意思是前i个品种还有m个空位(摆放0个花)时,方案数只有1.

      

    #include <cstdio>
    
    int n, m, a[105];
    long long dp[105][105];
    
    
    int main()
    {
        //freopen("1.in", "r", stdin);
        //freopen("1.out", "w", stdout);
        
        scanf("%d%d", &n, &m);
        for(int i=1; i<=n; i++)
            scanf("%d", &a[i]);
        
        for(int i=0; i<n; i++)
            dp[i][m] = 1;
        
        for(int i=1; i<=n; i++)
            for(int j=m-1; j>=0; j--)
                for(int k=0; k<=a[i] && k+j<=m; k++)
                {
                    //k表示当前品种摆放数目
                    dp[i][j] += dp[i-1][j+k];
                    dp[i][j] %= 1000007;
                }
        /*
        for(int i=0; i<=n; i++)
        {
            for(int j=0; j<=m; j++)
                printf("(%d,%d)%lld ", i, j, dp[i][j]);
            printf("
    ");
        }*/
        printf("%lld", dp[n][0]);
        return 0;
    }

    怕是要退役。。。

  • 相关阅读:
    Linux 文件及目录管理命令基础
    MHA高可用及读写分离
    MySQL的备份和回复
    mysql的主从复制
    MySQL索引管理及执行计划
    [LeetCode]Linked List Cycle II解法学习
    浅谈reverse_iterator的base()函数
    [LeetCode]LRU Cache有个问题,求大神解答【已解决】
    分享一篇不错的博文《写给准备参加秋招的学弟学妹们~一定要来看哦~》
    将博客搬至CSDN
  • 原文地址:https://www.cnblogs.com/yBaka/p/7745807.html
Copyright © 2020-2023  润新知