栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

信息学奥赛一本通 1293:买书 | OpenJudge NOI 2.6 6049:买书

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

信息学奥赛一本通 1293:买书 | OpenJudge NOI 2.6 6049:买书

【题目链接】

ybt 1293:买书
OpenJudge NOI 2.6 6049:买书

【题目考点】 1. 动态规划:完全背包

完全背包求方案数

【解题思路】

该问题为完全背包求方案数的问题。

1. 状态定义

集合:每种书买多少本构成的方案
限制:在前多少种书中买,买书钱数
属性、条件:书价钱加和等于买书钱数
统计量:方案数
状态定义:dp[i][j]:在前i种书中选书购买,总价钱为j元的方案数
初始状态:在前i种书中选书购买,总价格为0元的方案,就是不选书,有一种方案。即dp[i][0]=1

2. 状态转移方程

记a[i]为第i种书的价钱
集合:在前i种书中选择书价钱加和为j的方案
分割集合:是否选择第i种书

  • 如果选择一本第i种书,接下来要在前i种书中选择书,价钱加和为j-a[i],方案数为:dp[i][j-a[i]]
  • 如果不选择第i种书,接下来要在前i-1种书中选择书,价钱加和为j,方案数为dp[i-1][j]
  • 两种情况的方案数加和,为在前i种书中选择书价钱加和为j的方案数,即dp[i][j] = dp[i][j-a[i]] + dp[i-1][j]

可以进行滚动数组优化。

【题解代码】 解法1:基本解法
#include
using namespace std;
#define N 15
#define M 1005
int n, m, a[N] = {0, 10, 20, 50, 100};//a[i]:第i本书的钱数 
int dp[N][M];//dp[i][j]:在前i种书中选书购买,总价钱为j元的方案数
int main()
{
    m = 4;//书的种类 
    cin >> n;
    for(int i = 0; i <= m; ++i)
        dp[i][0] = 1;
    for(int i = 1; i <= m; ++i)
        for(int j = 1; j <= n; ++j)
        {
            if(j >= a[i])
                dp[i][j] = dp[i][j-a[i]] + dp[i-1][j];
            else
                dp[i][j] = dp[i-1][j];
        }
    cout << dp[m][n];
    return 0;
}
解法2:滚动数组优化
#include
using namespace std;
#define N 15
#define M 1005
int n, m, a[N] = {0, 10, 20, 50, 100};//a[i]:第i本书的钱数 
int dp[M];//dp[i][j]:在前i种书中选书购买,总价钱为j元的方案数
int main()
{
    m = 4;//书的种类 
    cin >> n;
    dp[0] = 1;
    for(int i = 1; i <= m; ++i)
        for(int j = a[i]; j <= n; ++j)
            dp[j] = dp[j-a[i]] + dp[j];
    cout << dp[n];
    return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/883746.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号