P1077 摆花

作者: yuq329 | 来源:发表于2020-05-27 22:35 被阅读0次

P1077 摆花

题目描述

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

输入格式

第一行包含两个正整数nm,中间用一个空格隔开。
第二行有n个整数,每两个整数之间用一个空格隔开,依次表示a_1,a_2,…,a_n

输出格式

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

输入输出样例

输入
2 4
3 2
输出
2

说明/提示

【数据范围】

对于20%数据,有0<n≤8,0<m≤8,0≤a_i≤8

对于50%数据,有0<n≤20,0<m≤20,0≤a_i≤20

对于100%数据,有0<n≤100,0<m≤100,0≤a_i≤100

NOIP 2012 普及组 第三题

解题思路

可以考虑动态规划,定义状态dp[i][j]表示前i种花占有前j个位置的方案数,那么可以看出dp[i][j]只与dp[i-1][j-k](前i-1种花占有前j-k个位置的方案数)有关,此处的k即为第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]) % M;

可以得到c++代码

#include <iostream>

#define M 1000007
#define ll long long
using namespace std;
const int maxn = 101;
ll dp[maxn][maxn];
int a[maxn];

int main() {
    int n, m;
    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]) % M;

    cout << dp[n][m];
}

DP优化利用滚动数组,降低内存消耗

#include <iostream>

#define M 1000007
using namespace std;
const int maxn = 101;
int dp[2][maxn], a[maxn], t;

int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) cin >> a[i];

    dp[0][0] = 1;

    for (int i = 1; i <= n; ++i) {
        t = 1 - t;
        for (int j = 0; j <= m; j++){
            dp[t][j] = 0;
            for (int k = 0; k <= min(a[i], j); ++k)
                dp[t][j] = (dp[t][j] + dp[1 - t][j - k]) % M;
        }
    }
    cout << dp[t][m];
}

DP优化 转变为一维动态规划,01背包问题
问题可以看作\sum_{i=1}^n{a_i}盆花按顺序排列,挑选出m盆的方案数
dp[i]表示长度为i的子序列有多少种.

#include <iostream>

#define M 1000007
using namespace std;
const int maxn = 101;
int dp[maxn], a[maxn];

int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) cin >> a[i];

    dp[0] = 1;
    for (int i = 1; i <= n; ++i)
        for (int j = m; j >=0; --j)//倒序,防止使用到已经处理过的dp[j - k]
            for (int k = 1; k <= min(a[i], j); ++k)
                //前i盆花可以取到j位置的方案数
                dp[j] = (dp[j] + dp[j - k]) % M;
    cout << dp[m];
}

搜索方法深度优先遍历

//来自:https://www.luogu.com.cn/blog/chenzhengyv/ti-xie-p1077-bai-hua-post
#include<bits/stdc++.h>
using namespace std;
const int maxn=105, mod = 1000007;
int n, m, a[maxn];
int dfs(int x,int k)
{
    if(k > m) return 0;
    if(k == m) return 1;
    if(x == n+1) return 0;
    int ans = 0;
    for(int i=0; i<=a[x]; i++) ans = (ans + dfs(x+1, k+i))%mod;
    return ans;
}
int main()
{
    cin>>n>>m;
    for(int i=1; i<=n; i++) cin>>a[i];
    cout<<dfs(1,0)<<endl;
    return 0;
}

记忆化搜索

//来自:https://www.luogu.com.cn/blog/chenzhengyv/ti-xie-p1077-bai-hua-post
#include<bits/stdc++.h>
using namespace std;
const int maxn=105, mod = 1000007;
int n, m, a[maxn], rmb[maxn][maxn];
int dfs(int x,int k)
{
    if(k > m) return 0;
    if(k == m) return 1;
    if(x == n+1) return 0;
    if(rmb[x][k]) return rmb[x][k]; //搜过了就返回
    int ans = 0;
    for(int i=0; i<=a[x]; i++) ans = (ans + dfs(x+1, k+i))%mod;
    rmb[x][k] = ans; //记录当前状态的结果
    return ans;
}
int main()
{
    cin>>n>>m;
    for(int i=1; i<=n; i++) cin>>a[i];
    cout<<dfs(1,0)<<endl;
    return 0;
}

相关文章

  • P1077 摆花

    P1077 摆花 题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共盆。通过调查顾客的喜好,...

  • 插图与原文

    插图与原文 花摊 碧桃摆了缤纷的花摊 美人梅摆了妩媚的花摊 玉兰摆了绰约的花摊 樱花摆了温婉的花摊 海棠摆了烂漫的...

  • 家里的摆花

    最近陪宝宝唱儿歌唱到脑袋里都是旋律 然后一不小心就在人前唱出来 Mew mew mew mew

  • 家里如何摆花

    现在考虑要绿植给家里做软装。 该怎么弄? 书房,台面可以摆,书柜顶部可以放一棵垂吊植物。 南阳台,可以再添两盆垂吊...

  • 从签售会书被抢说起来

    今天我们社在展览会上有两个新书发布会。我们按照常规流程,摆台,摆书花,等着发布会的开始。 摆完书花,我下台看造型好...

  • 习惯了他的习惯,喜欢上了他的喜欢。

    大凡懂点生活情趣的人都知道,家里摆花,是一种艺术,一种点缀。 不论花有多么名贵、多么鲜艳,家里的花摆的多了,反而显...

  • 路中间的摆花

    今天路上的车很多,每个人的车速都不快,我也悠闲地开着车,打发着堵车的时间,我发现一个有意思的事情,路中间的...

  • 喇叭花

    上喇叭花,摆盘效果图

  • 感时花溅泪

    《殇花》 ——路过 赏遍百花秀 春尽不知愁 举镜摆姿色 不觉花泪流

  • 雨路

    风卷黑云天际边, 树摇花摆雨如烟。 ...

网友评论

    本文标题:P1077 摆花

    本文链接:https://www.haomeiwen.com/subject/gzhnahtx.html