动态规划做题总结

下面包含最近做过的比较有价值的动态规划的题目以及简要题解,并附上了有注释,较为易懂的AC代码。

UVaOJ(紫书习题)

1. UVA10163:题目要求最小值的最大,这启发我们二分答案。之后还要求求出花费的最小值,这就相当于01背包了,状态及状态转移方程:我的代码

// dp[cur][cnt]: mininum cost when dealing with p[cur] and already cnt storages safe
// dp[cur][cnt] = min dp[cur+1][cnt], dp[cur+1][cnt+p[cur]/l] + p[cur] (if possible)
// Corner: dp[m+1]: if cnt < n then inf else 0;
// Goal: dp[1][0]

2. UVA1631:多阶段决策。每个状态dp[cur][num_{cur}][num_{cur+1}]保存已经让1~cur-1归位,现在正在考虑第cur位,并且目前cur处和cur+1位的数分别是num_cur与num_cur+1,状态转移方程是:我的代码

dp[i][j][k] = min(dp[i][j][k], dp[i+1][j+ch2][k+ch3])

3. UVA12589 Learning Vector:多阶段决策问题。首先一个重要的观察是应当对向量按斜率排序,这样可以做到无后效性。由此我们用dp[ypos][cur]保存考虑到第cur个向量时y轴坐标,状态转移方程:我的代码

dp[i][j] = max dp[pos+y[k]][cur+1]+(2*ypos+y[k])*x[k]

4. Chopsticks UVA - 10271 :多阶段决策问题。重要观察是选的那两根短筷子一定要长度相邻,这样就变成01背包了。dp[cur][cnt]保存状态。注意检查每一状态是否可以选出长筷子(我最后用的是cur - 1 < 3 * cnt与开头注释不一样),注意本题记忆化搜索很慢,1890 ms!状态转移方程见下方,我的代码

dp[cur][cnt] = min(dp[cur+1][cnt], dp[cur+2][cnt+1]+val[cur] if ok)

 

Codeforces

1. Educational 49 E. Inverse Coloring:首先要明确画出第一行和第一列之后,方案就已经确定了。那么最大矩形也就是第一行中最长连续同色子序列与第一列中的乘积,这两者实际可以用一次dp求出,但是最后不要忘记答案除以二,因为第一行第一列的方格被考虑了两次。另外这种方法是O(n^3)的,可能会爆内存,这里采用了滚动数组。我的代码

2. Educational Codeforces Round 50 (Rated for Div. 2), problem: (C) Classy Numbers

这可以使用数位dp来完成。从最高位向个位依次填数字,如果存在某一位已经小于原数了,就用公式O(1)计算;否则根据这一位是否是1进行dp。我的代码

3. Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final), problem: (D) Recovering BST

区间dp,dp[l][r][0/1]含义具体见代码:(这道n^3复杂度的题n<=700,但记忆化搜索跑得飞快,才61ms)我的代码

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值