原题单链接:https://rentry.org/ozd34yrn
例题
- 重述问题
- 找到最后一步
- 去掉最后一步,是否能划分出子问题
- 考虑边界
const int N=1010;
class Solution {
public:
int mem[N];
int dfs(vector<int>& cost, int x)
{
if(mem[x])return mem[x];
int sum=0;
if(x==1||x==0)sum=0;
else sum=min(dfs(cost,x-1)+cost[x-1],dfs(cost,x-2)+cost[x-2]);
mem[x]=sum;
return sum;
}
int minCostClimbingStairs(vector<int>& cost) {
int n=cost.size();
// int ans=dfs(cost,n);
int f[N];
f[0]=f[1]=0;
for(int i=2;i<=n;i++)
{
f[i]=min(f[i-1]+cost[i-1],f[i-2]+cost[i-2]);
}
return f[n];
}
};
const int N = 3010;
class Solution {
public:
int mem[N];
int dfs(vector<int>& nums, int x) {
if (mem[x])
return mem[x];
int res = 0;
for (int i = 0; i < x; i++) {
if (nums[i] < nums[x]) {
res = max(res, dfs(nums, i) + 1);
}
}
mem[x] = res;
return res;
}
int lengthOfLIS(vector<int>& nums) {
int n = nums.size();
int res=-1e9;
// for(int i=0;i<n;i++)
// {
// res=max(res,dfs(nums,i)+1);
// }
int f[N];
for (int i = 0; i < n; i++) {
f[i] = 1;
for (int j = 0; j < n; j++) {
if (nums[j] < nums[i]) {
f[i] = max(f[i], f[j] + 1);
}
}
}
for(int i=0;i<n;i++)
{
res=max(res,f[i]);
}
return res;
}
};
const int N = 10010;
class Solution {
public:
int mem[N];
int dfs(vector<int>& coins, int amount) {
if (mem[amount])
return mem[amount];
int n = coins.size();
if (amount == 0)
return 0;
int res = 1e9;
for (int i = 0; i < n; i++) {
if (amount >= coins[i])
res = min(res, dfs(coins, amount - coins[i]) + 1);
}
mem[amount] = res;
return res;
}
int coinChange(vector<int>& coins, int amount) {
int n = coins.size();
// int ans = dfs(coins, amount);
// ans=ans==1e9?-1:ans;
int f[N];
memset(f, 0x3f, sizeof f);
f[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int j = 0; j < n; j++) {
if(i>=coins[j])
f[i]=min(f[i], f[i-coins[j]] + 1);
}
}
return f[amount]>1e9?-1:f[amount];
}
};
const int N=100010;
class Solution {
public:
int mem[N];
int dfs(vector<int>& sales,int x)
{
if(x<0)return 0;
if(mem[x])return mem[x];
int res=-1e9;
res=max(sales[x],dfs(sales,x-1)+sales[x]);
mem[x]=res;
return res;
}
int maxSales(vector<int>& sales) {
int n=sales.size();
int f[N];
int ans=-101;
// for(int i=0;i<n;i++)
// {
// ans=max(ans,dfs(sales,i));
// }
f[0]=sales[0];
for(int i=1;i<n;i++)
{
f[i]=max(sales[i],f[i-1]+sales[i]);
}
for(int i=0;i<n;i++)
{
ans=max(ans,f[i]);
}
return ans;
}
};
const int N=110;
class Solution {
public:
int mem[N]={0};
int dfs(int x)
{
if(mem[x])return mem[x];
if(x==0)return 1;
int res=0;
for(int i=1;i<x;i++)
{
res=max(res,max(i*(x-i),dfs(x-i)*i));
}
return mem[x]=res;
}
int integerBreak(int n) {
int ans;
// ans=dfs(n);
int dp[N];
dp[0] = dp[1] = 1;
for (int i = 2; i <= n; ++i) {
for (int j = 1; j < i; ++j) {
dp[i] = max(dp[i], max(j * (i - j), dp[i - j] * j));
}
}
ans=dp[n];
return ans;
}
};
下期待更新的dp题单(2024.2.25编)
413. 等差数列划分 如果满足等差,则f[i] = f[i – 1] + 1, 否则为0
279. 完全平方数 简单预处理,最后一步:选择某个数作为最后一个
376. 摆动序列 考虑相邻两个数大小问题,枚举选哪个模型,dp转移可以直接01转移
2786. 访问数组中的位置使分数最大 枚举每个数选或不选,记录上的数的奇偶性,01转移 实现dfs不需要传vector的参数
368. 最大整除子集 pre数组记录路径,更新时实现记录,而不是以前的max不知道更新没更新
01转移
376. 摆动序列 考虑相邻两个数大小问题,枚举选哪个模型,dp转移可以直接01转移