您的位置:首页 > 编程语言 > C语言/C++

NOIP 2012 - 普及组 摆花 递推 重庆一中高2018级竞赛班第六次测试 2016.7.31 Problem 3

2016-08-02 18:57 239 查看
【问题描述】

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

【输入格式】

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

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

【输出格式】

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

【输入样例】

2 4
3 2


【输出样例】

2


【输入输出样例说明】

有 2 种摆花的方案,分别是(1,1,1,2), (1,1,2,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。

思路:这道题要求方案数,很明显需要用DP完成。但是考试的时候把下面方程中的min想成了max(我也不知道为什么),反正方程就是下面这个。

递推方程:f[i][j]=f[i-1][j]+f[i-1][j-1]+f[i-1][j-2]+……+f[i-1][j-min(a[i],j)];

/*
Name: flower.cpp
Copyright: Twitter & Instagram @stevebieberjr
Author: @stevebieberjr
Date: 02/08/16 19:06
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,m,a[105],f[105][105]; //f[i][j]:前i种花放j盆的方案数

/*递推方程:f[i][j]=f[i-1][j]+f[i-1][j-1]+f[i-1][j-2]+...+f[i-1][j-min(a[i],j)];*/

int main()
{
freopen("flower.in","r",stdin);
freopen("flower.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(f,0,sizeof(f));

for(int i=0;i<=n;i++)
{
f[i][0]=1;
} //边界

for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int t=min(a[i],j);
for(int k=0;k<=t;k++)
{
f[i][j]+=f[i-1][j-k]%1000007;
}
}
}
printf("%d\n",f
[m]%1000007);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp noip 递推 c++
相关文章推荐