摆花

题目描述

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

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

输入格式

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

第二行有nnn个整数,每两个整数之间用一个空格隔开,依次表示a1,a2,…,ana_1,a_2,…,a_na1,a2,,an

输出格式

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

输入输出样例

输入 #1
2 4
3 2
输出 #1
2

说明/提示

【数据范围】

对于20%数据,有0<n≤8,0<m≤8,0≤ai≤80<n≤8,0<m≤8,0≤a_i≤80<n8,0<m8,0ai8;

对于50%数据,有0<n≤20,0<m≤20,0≤ai≤200<n≤20,0<m≤20,0≤a_i≤200<n20,0<m20,0ai20;

对于100%数据,有0<n≤100,0<m≤100,0≤ai≤1000<n≤100,0<m≤100,0≤a_i≤1000<n100,0<m100,0ai100。

NOIP 2012 普及组 第三题

【解题思路】

这一题乍一看有些难度,理解后看一下觉得其实还蛮简单的。主要思路是:先开一个二维数组b[][],存储放i种j盆花的方案总数。首先进行初始化,大家想想无论有多少种花,如果一盆都没有,那是不是只有一种方案总数了(什么也不放)?所以初始化为b[i][0]=1(0<=i<=m)。然后呢,我们进行三重循环。变量i表示有多少种花,j表示有多少盆花,k则是用于计算某种花放多少盆。从总盆数开始循环到总盆数-最大盆数,如果k小于0(说明最大盆数大于总盆数)就退出循环。我们得到的状态转移方程则是:b[i][j]+=b[i-1][k](j>=k>=j-a[i]);当然,随时加上%1000007会更保险(不要问我最后加能得多少分)。然后,然后就AC啦。

【code】

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 const int Mod=1000007;
 6 int n,m,a[105],f[105][105];
 7 int main(){
 8     //freopen("1077.in","r",stdin);
 9     //freopen("1077.out","w",stdout);
10     scanf("%d%d",&n,&m);
11     f[0][0]=1;
12     for(register int i=1;i<=n;i++)
13         scanf("%d",&a[i]);
14     for(register int i=1;i<=n;i++)
15         for(register int j=m;j>=0;j--)
16             for(register int k=0;k<=a[i]&&j-k>=0;k++)
17                 f[i][j]+=f[i-1][j-k]%Mod;
18     printf("%d\n",f[n][m]%Mod);
19     return 0;
20 }

 

 

posted @ 2019-07-25 23:06  GTR_PaulFrank  阅读(254)  评论(0编辑  收藏  举报