小菜的算法学习笔记3.26

今天发现了一道非常棒的题,先上链接
https://www.luogu.com.cn/problem/P1077
这个题棒就棒在不仅可以用搜索(必须得是记忆化搜索,单纯的搜索会超时)来做,还可以用动态规划来做,还可以用01背包解决,还可以用前缀和优化和数学知识解决,由于我还涉世(suan fa)未深,所以只对记忆化搜索、动态规划和01背包进行了研究。
昨天做这道题的时候我最先想到的是动态规划,花费了将近一小时研究,虽然和答案很像了,但是还是没AC…
先说说动态规划的方法吧,dp[i][j]表示前i种花摆j盆有多少种方法,动态转移方程为 dp[i][j]=dp[i][j]+dp[i-1][j-k] 由于要取1000007的模,为了避免超出int类型范围,所以这里要加一个取余运算

dp[i][j]=(dp[i][j]+dp[i-1][j-k])%1000007;

意思为:前i种花摆j盆的方法等于前i-1种花摆[j-m,j]盆花的方法和,其中m为min(j,a[i]),即取第i种花最多可摆的数目和可摆花数目的最小值,其实很好理解,但是不太好解释…只能是多做题才能悟出来吧…我昨天就是栽在这里了…
然后要进行初始化,根据事实,如果可摆的花数目为0的时候,则全置为1

for(int i=0;i<=n;i++){
   
        dp[i][0]=1;
    }

最后输出dp[n][m]就是结果了
动态规划AC代码:

#include <iostream>

using namespace std;
#define N 1000007
int n,m,a[105];
long long dp[105][105];
int main(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值