1047 [NOIP2012]摆花 背包DP 递推求方案数
作者:互联网
链接:https://ac.nowcoder.com/acm/contest/24213/1047
来源:牛客网
题目描述
小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m 盆。通过调查顾客的喜好,小明列出了顾客最喜欢的n 种花,从1 到n 标号。为了在门口展出更多种花,规定第i 种花不能超过ai 盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列。
试编程计算,一共有多少种不同的摆花方案。
输入描述:
第一行包含两个正整数n和m,中间用一个空格隔开。 第二行有n个整数,每两个整数之间用一个空格隔开,依次表示a1、a2、……an。输出描述:
输出只有一行,一个整数,表示有多少种方案。注意:因为方案数可能很多,请输出方案数对1000007取模的结果。
示例1输入
复制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。
分析
数据范围不大,一般100左右n^3 , 1000~几k 左右n^2, 往上就是nlog 或者n了
这题问的是选择问题,所以n^3 的 背包DP递推求方案数即可
设dp[i][j] 表示前i个数,选择j个花盆的总方案数,对于每个物品都有可以选择0 ~ a[i] 个,遍历所有满足条件的个数即可。
#include<bits/stdc++.h> using namespace std; const int N = 200,mod = 1000007; int dp[N][N],a[N]; #define fo(i,l,r) for(int i = l;i<=r;i++) #define of(i,r,l) for(int i = r;i>=l;i -- ) int main() { int n,m;cin>>n>>m; fo(i,1,n) cin>>a[i]; dp[0][0] = 1; fo(i,1,n) { fo(k,0,a[i]) { of(j,m,k) { dp[i][j] = (dp[i][j] + dp[i-1][j - k]) % mod; } } } // fo(i,1,n) { // fo(j,1,m) { // cout<<dp[i][j]<<' '; // }cout<<endl; // } cout<<dp[n][m] % mod; }
标签:摆花,1047,NOIP2012,方案,int,0i,dp,fo 来源: https://www.cnblogs.com/er007/p/16489087.html