当前位置: 首页 > news >正文

Dynamic Programming【DP】1

问题 A: Dice Combinations

题目描述

Your task is to count the number of ways to construct sum n by throwing a dice one or more times. Each throw produces an outcome between 1 and  6.
For example, if n=3, there are 4 ways:

1+1+1
1+2
2+1
3

输入

The only input line has an integer n.
Constraints
1 ≤ n ≤ 106

输出

Print the number of ways modulo 109+7.

样例输入

复制

3
样例输出

复制

4

在计算 dp[i] 时,判断条件用 i >= j 而不是 i > j,是因为当 i == j 时,这种情况是合法且需要被计入的

我们结合具体场景理解:

核心逻辑回顾

dp[i] 表示 “得到总和 i 的方式数”,其递推公式的思路是:
最后一次掷出的数字为 j(1≤j≤6),则之前的总和必须是 i - j
因此,只有当 i - j ≥ 0 时,i - j 才是一个有效的 “之前的总和”(总和不能为负数),对应的情况才能被计入 dp[i]

为什么 i >= j 是正确的?

当 i == j 时:

  • i - j = 0,即 “之前的总和为 0”(对应 dp[0] = 1,表示 “不掷骰子” 的基础状态)。

  • 这种情况的实际意义是:直接通过一次掷出 j(此时 j = i)得到总和 i

例如,i=3j=3 时:

  • i >= j 成立(3 >= 3),因此 dp[3] 会累加 dp[0](值为 1)。

  • 这对应 “直接掷出 3” 这一种方式,是题目中明确要求计入的(如样例中 n=3 的第 4 种方式)。

若用 i > j 会怎样?

如果判断条件是 i > j,则当 i == j 时(如 i=3, j=3)会被排除,导致:

  • dp[i] 中缺少 “直接掷出 i” 这一种方式,结果偏小。

  • 例如 i=3 时,dp[3] 会漏掉 dp[0] 的贡献,计算结果为 dp[2] + dp[1] = 2 + 1 = 3,与正确答案 4 不符。

结论

i >= j 是正确的,因为它包含了 “最后一次掷出的数字恰好等于 i” 的合法情况(此时 i - j = 0,对应 dp[0] 的贡献)。而 i > j 会错误地排除这种情况,导致结果不正确。

代码 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const int mod=1e9+7;ll n,dp[N];int main()
{	cin>>n;dp[0]=1;for(int i=1;i<=n;++i){for(int j=1;j<=6&&i-j>=0;++j){dp[i]=(dp[i]+dp[i-j])%mod;}}cout<<dp[n];return 0;
}

问题 B: Minimizing Coins

题目描述

Consider a money system consisting of n coins. Each coin has a positive integer value. Your task is to produce a sum of money x using the available coins in such a way that the number of coins is minimal.
For example, if the coins are {1,5,7} and the desired sum is 11, an optimal solution is 5+5+1 which requires 3 coins.

输入

The first input line has two integers n and x: the number of coins and the desired sum of money.
The second line has n distinct integers c1,c2,...,cn: the value of each coin.
Constraints
1 ≤ n ≤ 100
1 ≤ x ≤ 106
1 ≤ ci ≤ 106

输出

Print one integer: the minimum number of coins. If it is not possible to produce the desired sum, print -1.

样例输入

复制

3 11
1 5 7
样例输出

复制

3

代码 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;int n,x,coin[N];
vector<int>dp(N,1e9);int main()
{cin>>n>>x;for(int i=0;i<n;++i)cin>>coin[i];sort(coin,coin+n);dp[0]=0;for(int i=1;i<=x;++i){for(int j=0;j<n&&coin[j]<=i;++j){dp[i]=min(dp[i],dp[i-coin[j]]+1);}}if(dp[x]!=1e9)cout<<dp[x];else cout<<"-1";return 0;
}

问题 C: Coin Combinations I 

题目描述

Consider a money system consisting of n coins. Each coin has a positive integer value. Your task is to calculate the number of distinct ways you can produce a money sum x using the available coins.
For example, if the coins are {2,3,5} and the desired sum is 9, there are 8 ways:

2+2+5
2+5+2
5+2+2
3+3+3
2+2+2+3
2+2+3+2
2+3+2+2
3+2+2+2

输入

The first input line has two integers n and x: the number of coins and the desired sum of money.
The second line has n distinct integers c1,c2,...,cn: the value of each coin.

Constraints

1 ≤ n ≤ 100
1 ≤ x ≤ 106
1 ≤ ci ≤ 106

输出

Print one integer: the number of ways modulo 109+7.

样例输入

复制

3 9
2 3 5
样例输出

复制

8

结果重复计数的原因是没有区分硬币的使用顺序,导致相同组合因顺序不同被多次统计。

代码 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const int mod=1e9+7;int n,x,coin[N];
vector<int>dp(N,0);int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin>>n>>x;for(int i=0;i<n;++i)cin>>coin[i];sort(coin,coin+n);dp[0]=1;for(int i=1;i<=x;++i){for(int j=0;j<n&&coin[j]<=i;++j){dp[i]=(dp[i]+dp[i-coin[j]])%mod;}}cout<<dp[x];return 0;
}

问题 D: Coin Combinations II

如上题,附加要求方案不能重复。

  1. 遍历顺序调整
    先遍历硬币(for(int j=0;j<n;++j)),再遍历金额(for(int i=c;i<=x;++i))。这种方式确保:

    • 每种硬币只能被 “按顺序” 使用,例如先用完所有 2 元,再用 3 元,最后用 5 元。
    • 避免了 “2+3” 和 “3+2” 被算作两种不同方案的问题。
  2. 金额遍历范围
    对于硬币 c,只从 i=c 开始遍历,因为只有金额 >= c 时才能使用该硬币,提高效率。

    for(int i=0;i<n;++i){for(int j=1;j<=x;++j){if(j>=coin[i])dp[j]=(dp[j]+dp[j-coin[i]])%mod;}}

问题 E: Removing Digits 

题目描述

You are given an integer n. On each step, you may subtract one of the digits from the number.
How many steps are required to make the number equal to 0?

输入

The only input line has an integer n.
Constraints
1 ≤ n ≤ 106

输出

Print one integer: the minimum number of steps.

样例输入

复制

27
样例输出

复制

5
提示

An optimal solution is 27 → 20 → 18 → 10 → 9 → 0.

对于每个数字 i,枚举其所有数位 dd 是 i 的每一位上的数字,且 d > 0),则:
dp[i] = min(dp[i], dp[i - d] + 1)
(含义:从 i 减去 d 后得到 i-d,步骤数比 dp[i-d] 多 1)

  • dp[27] 的计算需要考虑其数位 2 和 7

    • 若减去 7,则 dp[27] = dp[20] + 1

    • 若减去 2,则 dp[27] = dp[25] + 1

  • 最终通过递推,dp[27] 会取两种选择中的最小值,得到最少步骤数。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;int n;
vector<int>dp(N,1e9);int main()
{cin>>n;dp[0]=0;for(int i=1;i<=n;++i){int temp=i;while(temp){int x=temp%10;if(i>=x&&x)dp[i]=min(dp[i],dp[i-x]+1);temp/=10;}}cout<<dp[n];return 0;
}

http://www.dtcms.com/a/314962.html

相关文章:

  • 【Linux】gdb cgdb — 基操
  • 广东省省考备考(第六十六天8.4)——判断推理(强化训练)
  • 竞品分析爬虫实现方案
  • Adobe Experience Manager (AEM) Assets|企业级数字资产管理平台(DAM)
  • 【DAB收音机】DAB服务跟随Service Follow功能介绍(一)
  • RAG常见问题与优化方法全解析|从新手到高手的实践指南
  • 【Spring】SpringBoot 自动配置,@ComponentScan、@Import、ImportSelector接口
  • 下载 | Windows Server 2025官方原版ISO映像!(7月更新、标准版、数据中心版、26100.4652)
  • Android工程命令行打包并自动生成签名Apk
  • MySQL 8.0源码编译安装
  • The Gang
  • 30天入门Python(基础篇)——第31天:标准库学习之re模块
  • 采集像列车:任务如何不脱轨、数据如何不漏采
  • 密码学基础知识总结
  • 【YOLO系列】YOLOv12详解:模型结构、损失函数、训练方法及代码实现
  • uniapp 基础(三)
  • 入门MicroPython+ESP32:PWM呼吸灯
  • 华清远见25072班C语言学习day1
  • 机器学习【六】readom forest
  • 不良事件管理系统,PHP不良事件系统源码,实现事件系统化统计分析,查找根本原因,从而进行改进
  • 【传奇开心果系列】Flet图片由小到大动画加轮播展示组件样式自定义模板
  • 【电路测试】如何测试电源纹波
  • Hive_sql如何计算连续签到天数
  • word常见问题汇总
  • 无偿分享120套开源数据可视化大屏H5模板
  • Fiddler 中文版怎么用 实现接口抓包调试与前后端联调闭环
  • Harmon、TokLIP论文解读
  • Flask全栈入门:打造区块链艺术品交易所
  • RTX5060显卡安装cuda版本PyTorch踩坑记录
  • 疏老师-python训练营-Day35模型可视化推理