Cow Cash G (动态规划 完全背包)
题目大意:
解题思路:
这似乎是一道很好的爆搜题,但是我们还是得跟着那句老话走
能用动态规划就别用别的
动态规划,AC可以变得很神奇,但是思考状态转移的时候真的可以让人脑袋爆掉!!
那么切回正题,这题怎么做?
看到货币可以无限使用,那么不难发现这是一道类似于完全背包的动规了
首先设定状态,我们将 i i i的方案数表示为 d p i dp_i dpi。接下来,我们考虑阶段——设我们为了组合出 i i i,我们选择一张面值为 a i a_i ai 的货币来尝试组合,那么他的方案数变成了 d p i − a i dp_{i-a_{i}} dpi−ai,如果选择用面值为 a i + 1 a_{i+1} ai+1 的货币来尝试组合 i i i ,那么方案数就变成了 d p i − a i + 1 dp_{i-a_{i+1}} dpi−ai+1 ……
一直这么下去,方程不就出来了吗?
d p i + = d p i − a i dp_i+=dp_{i-a_{i}} dpi+=dpi−ai
接下来,我们解决最后一个问题,
d
p
dp
dp 数组的初始状态是什么?
因为
d
p
i
dp_i
dpi 表示
i
i
i 的方案数,所有我们可以自然而然的从
d
p
0
dp_0
dp0 开始思考初始状态——我们也能自然而然的认为
d
p
0
dp_0
dp0 的初值是0——也正是因为这个错误,我整个程序崩了,甚至让我以为是我的转移方程推错了!!
不要只记得状态转移方程,初值的问题也值得我们重视
我们可以选择换一个思路理考货币所组成的价钱:
例如:
组成一个 18 单位面值的货币可以是这样的:8×2+2×1
其实我们可以在这条分解式后面再加一个虚无的货币面值:8×2+2×1 + 0
或许有人会问,+0和不+0的面值都是一致的,那么这么做有什么意义?其实不然,我们可以这么理解这个 0,把他看成一个没有面值的货币。什么意思呢?就是 0 其实是一种货币,只不过没有面值而已。是的,我们要把 0 看成一种实际存在的货币。
然后我们再回到 d p 0 dp_0 dp0 初值的问题,0这个单位面值无法用任何正常的货币构成,因此我一开始也认为 d p 0 dp_0 dp0 就是0,但是现在我们拥有了 货币0 这种假想,所以我们目前的 d p 0 dp_0 dp0 的构成情况应该是这样的:
d p 0 = 1 × 0 dp_0=1×0 dp0=1×0 (注意了,这里的0表示的是一种面值为0的货币!!)
现在我们发现,
d
p
0
dp_0
dp0 其实是有一种构成方案的,也就是说
d
p
0
dp_0
dp0 实际上应该等于1,因为有一种假想型的 0 货币可以构成它。而 0 这种特殊货币的存在也不会破坏其他
d
p
i
dp_i
dpi 的答案,也就是说哪怕有了新的货币0,构成
i
i
i 的可行方案依旧是
d
p
i
dp_i
dpi 种,不会因为 0 的出现而增多或减少。
这种种现象都证明,
d
p
0
=
1
dp_0=1
dp0=1是可行的。
但是,我之前不是说过 d p 0 = 0 dp_0=0 dp0=0吗?这就矛盾了呀!很简单,我之前说的是错的呗。
推敲出了 d p 0 = 1 dp_0=1 dp0=1 这个堪比状态转移方程的大条件,一切困难都迎刃而解。
CODE
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
long long n,v,a[1100];
long long dp[101000]={0};
void input()
{
cin>>n>>v;
for(int i=0;i<n;i++)
cin>>a[i];
}
void DP()
{
dp[0]=1;
for(int i=0;i<n;i++)
{
for(int j=a[i];j<=v;j++)
dp[j]+=dp[j-a[i]]; //用完全背包的思路来实现状态转移方程
}
cout<<dp[v];
}
int main()
{
input();
DP();
return 0;
}
总结:
蓦然回首,我们对动态规划的研究都集中在状态转移方程,对初始值的重视依旧不够,通过这道题,它告诉我们,初值确实重要
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!