题解:P1077 [NOIP2012 普及组] 摆花

lam_dyr

2025-01-07 19:59:09

Solution

曾经刚学 dp 时做的题现在能交题解了,写篇纪念一下吧。

题意

给定 n 种花,每种花的上限是 a_i,求摆放 m 盆花的方案数(同种花放一起,按编号从小到大摆放,结果对 1000007 取模)。

思路

dp_{i,j} 为考虑前 i 种花,摆放 j 盆花的方案数。

但是如何判断这是道 dp 题呢?算法标签。

但是你打比赛的时候是没有算法标签的,所以在这讲一下如何判断 dp 。

综上,本题适合用动态规划解决。

考虑如何转移。

对于第 i 种花,可以摆放 k( 0 \le k \le \min (a_i, j) )

因此,当计算 dp_{i,j} 时,可以累加前 i-1 种花摆放 j-k 盆的方案数,也就是 dp_{i,j} = \sum dp_{i-1,j-k}

细节:

Code

#include <iostream>
#include <algorithm>
using namespace std;
const int MOD=1000007;
int dp[105][105];
int n,m;
int a[105];
int main() {
    cin>>n>>m;
    for(int i=1;i<=n;++i) 
        cin>>a[i];
    dp[0][0]=1;
    for(int i=1;i<=n;++i){
        for(int j=0;j<=m;++j){
            for(int k=0;k<=min(a[i],j);++k) 
                dp[i][j]=(dp[i][j]+dp[i-1][j-k])%MOD;
        }
    }
    cout<<dp[n][m];
    return 0;
}

写题解不易,点个赞再走呗~