zoukankan      html  css  js  c++  java
  • Vijos_1792_摆花_(动态规划,多重集组合数)

    描述


    https://vijos.org/p/1792

    共n种花,第i种花有a[i]个,要摆m个,同一种花连续且花按照序号从小到大排,问共有多少种摆花方案.

     

    描述

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

    格式

    输入格式

    【输入】
    输入文件共2行。第一行包含两个正整数n和m,中间用一个空格隔开。第二行有n个整数,每两个整数之间用一个空格隔开,依次表示a1、a2、……an。

    输出格式

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

    样例1

    样例输入1[复制]

    2 4
    3 2

    样例输出1[复制]

    2

    限制

    1S

    提示

    【输入输出样例说明】
    有2种摆花的方案,分别是(1,1,1,2),(1,1,2,2)。括号里的1和2表示两种花,比如第一个方案是前三个位置摆第一种花,第四个位置摆第二种花。

    来源

    NOIP2012普及组第三题

    分析


    由于花按照序号排放,所以对于任意一个选定的集合,集合中花的摆放顺序是唯一的,所以一个集合对应一种方案.问题就转化成了求多重集组合数.

    POJ_3046_Ant_Counting

    上面这道题里有详细的O(n*m)的算法介绍.这题数据水,O(n*m*m)的朴素算法也能过.

    注意:

    1.第二层循环里是 j<=m ,因为dp[i][j]表示的是前i种中拿j个(如果拿得过多方案数是0,不必考虑).

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn=100+5,mod=1e6+7;
     5 int n,m;
     6 int a[maxn];
     7 int dp[2][maxn];
     8 
     9 void solve(){
    10     dp[0][0]=dp[1][0]=1;
    11     for(int i=1;i<=n;i++)
    12         for(int j=1;j<=m;j++){
    13             if(j-1-a[i]>=0) dp[i&1][j]=(dp[(i-1)&1][j]+dp[i&1][j-1]-dp[(i-1)&1][j-a[i]-1]+mod)%mod;
    14             else dp[i&1][j]=(dp[(i-1)&1][j]+dp[i&1][j-1])%mod;
    15         }
    16     printf("%d
    ",dp[n&1][m]);
    17 }
    18 int main(){
    19     scanf("%d%d",&n,&m);
    20     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    21     solve();
    22     return 0;
    23 }
    View Code
  • 相关阅读:
    线程安全
    线程控制(阻塞、睡眠、让步)
    防止代码被扒
    一个demo学会js
    移动端Web页面问题解决方案
    利用ajax实现和后台交互的模糊搜索
    纯前端实现模糊搜索
    用Jquery控制文本框只能输入数字和字母
    博主收藏的前端框架,极力推荐!
    将阿拉伯数字转换为大写
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5527020.html
Copyright © 2011-2022 走看看