基础动态规划题目合集

1.abc291_d

水题,简单规划即可(自己的做法可见提交代码)

2.abc291_f

需要用到一点点思维和动态规划
官方解析:abc291_f_solution

3.牛客2023寒假集训营1 - M

\[dp[i][j]=\underset{k\leq j}{max}(dp[i-1][j-k]+\frac{k}{m-(j-k)}) \]

\(dp[i][j]\)表示将小波奇的m个仙贝已经分给i个人,共分出了j个仙贝时的最大好感度之和

4.cf 1741 E Sending a Sequence Over the Network

dp[i]表示到第i个位置,可以行程想要的a数组
之后遍历b数组,假设遇到的一个数可以作为左边界或者右边界,同时保证前面无缝接上前面已经可以实现a数组的部分,利用dp即可

5.abc262_d

此题仍待理解!=!
动态规划
i:1~n dp[j][k][l]代表前j个元素挑选k个元素,且这k个元素取余i的和为l(不知理解是否还存在问题)
详见提交代码和题解

6.abc 298 e Unfair Sugoroku

阿巴阿巴。。。说实话,自己做的话都没有发现可以运用动态规划来求解。。。
首先可以明白,Ta和Ao的位置大的部分影响T和A位置小的部分,而且位置小的部分由位置大的地方来决定,故可以使用动态规划来求解。
定义dp[i][j][f]为Ta在i位置,Ao在j位置时,Ta赢得概率(f=0意味着下一步由Ta走;f=1意味着下一步由Ao走)。
那么规划的初始条件就是

dp[i][n][f]=0;//Ao到了
dp[n][i][f]=1;//Ta到了

递推式也易知

\[dp[i][j][0]=\sum_{k=1}^{p}{dp[min(n,i+k)][j][1]} \]

\[dp[i][j][1]=\sum_{k=1}^{q}{dp[i][min(n,j+k)][0]} \]

之后遍历整个范围,最终的答案为dp[a][b][0]
具体代码见提交记录

7.abc 300 E Dice Product 3

动态规划,细节看官方题解,这里仅罗列结论
我们定义dp(n)表示从n开始到达题目所给的N的概率
那么,有\(dp(n)=\frac{dp(n)+dp(2n)+dp(3n)+dp(4n)+dp(5n)+dp(6n)}{6}\)
\(dp(n)=\frac{dp(2n)+dp(3n)+dp(4n)+dp(5n)+dp(6n)}{5}\);
而且当n>N时,dp(n)=0;dp(N)=1;
所以可以通过动态规划来求解,最终答案为dp(1)

8.abc 306 D Poisonous Full-Course

dp[course i][Takahashi’s state j]
The maximum total tastiness of the courses that he has eaten when he has decided whether to eat or skip for the first i courses and his state is j ( 0 … he has an healthy stomach, 1 … he has an upset stomach.)
递推过程:

// Note that 0-based indices are used for the courses in the sample code
// Initialize the DP table
for(long long i=0;i<=n;i++){
	dp[i][0]=-4e18; // dp[i][0] = -∞
	dp[i][1]=-4e18; // dp[i][1] = -∞
}
dp[0][0]=0; // Initially, he has a healthy stomach
for(long long i=0;i<n;i++){
	// Transition for his choice of eating the i-th course
	if(x[i]==0){
		dp[i+1][0]=max(dp[i][0],max(dp[i][0],dp[i][1])+y[i]);
	}
	else{
		dp[i+1][1]=max(dp[i][1],dp[i][0]+y[i]);
	}
	// Transition for his choice of skipping the i-th course
	dp[i+1][0]=max(dp[i+1][0],dp[i][0]);
	dp[i+1][1]=max(dp[i+1][1],dp[i][1]);
}

详可见代码

9.abc 270 D Stones

题意
给 n 个石头和一个 A 序列(个数为 k ),Takahashi and Aoki 轮流从石头堆中选取不超过当前石头数的且在 A 序列里的个数的石头并移除它。两个人都想自己移去的石头数目尽可能大,问你先手 Takahashi 能移除多少个石头?
思路
首先考虑贪心,会发现其实没法考虑完全!
考虑用动态规划求解这种复杂策略问题
状态:
定义 \(dp[i]\) 表示先手在面对 i 个的石头的局面可以取得的最大石子数】
初始 \(dp[a[i]] = a[i]\)
转移:
\(a[j] \le i\) 时,当前先手可以执行 \(a[j]\) 操作,让后手面对 \(i - a[j]\)局面,那么当前先手能取到的石子数最大值即为$i - dp[i - a[j]] $,所以遍历 \(i\) 下可能的 \(a[j]\),那么$dp[i] = max(dp[i], i - dp[i - a[j]]) $
从前往后遍历取大,最终答案即为 \(dp[n]\)

代码传送门

10.abc 312 D - Count Bracket Sequences

满足题意的字符串一定是任意前缀左括号数大于等于右括号数,整体左括号数等于右括号数
可以利用 DP 求解
状态
\(dp[i][j]\) 表示字符串第 i 个字符处,j 为前 i 个字符中左括号减右括号的个数,值即为方案数

转移
三个转移

  • $ss[i] = ( $,那么 $dp[i][j] -> dp[i + 1][j + 1] $
  • $ss[i] = ) $,那么 $dp[i][j] -> dp[i + 1][j - 1] $
  • $ss[i] = ? $,那么 $dp[i][j] -> dp[i + 1][j + 1] $ 且 $dp[i][j] -> dp[i + 1][j - 1] $

最终答案即为 $dp[n][0] $
代码传送门

11.cf 903 div.3 E. Block Sequence

状态
dp[i] 表示对区间 [i, n] 所需的最小操作次数使得其 beautiful
初值 dp[n] = 1, dp[n + 1] = 0

转移

  • dp[i] = dp[i + 1] + 1,移除当前第 i 个字符,延续成立
  • 考虑 i + a[i] + 1 的位置,其小于等于 n + 1 则传递 dp[i + a[i] + 1],不然a[i]就无法利用

两种转移取小即可

代码传送门

12.leetcode 546. 移除盒子

状态
\(dp[l][r][k]\) 表示移除区间 \([l, r]\) 和后面 \(k\)\(a_r\) 时所能得到的最大积分

转移

\[dp[l][r][k] = \max(dp[l][r - 1][0] + (k + 1) ^ 2, \max_{i = l}^{r - 1} \{ ( dp[l][i][k + 1] + dp[i + 1][r - 1][0] ) \times (b[i] == b[r]) \} ) \]

Qiansui_code

13.洛谷 P3842 [TJOI2007] 线段

状态
\(dp[i][0]\) 表示移动到第 i 行左端点所需的最短路程
\(dp[i][1]\) 表示移动到第 i 行右端点所需的最短路程

转移
初值:\(dp[1][0] = r[1] - 1 + r[1] - l[1] ; dp[1][1] = r[1] - 1 ;\)

\[\begin{aligned} dp[i][0] = min(dp[i - 1][0] + abs(r[i] - l[i - 1]) + r[i] - l[i] + 1, dp[i - 1][1] + abs(r[i] - r[i - 1]) + r[i] - l[i] + 1); \\ dp[i][1] = min(dp[i - 1][0] + abs(l[i] - l[i - 1]) + r[i] - l[i] + 1, dp[i - 1][1] + abs(l[i] - r[i - 1]) + r[i] - l[i] + 1); \end{aligned} \]

Qiansui_code

posted on 2023-02-28 15:00  Qiansui  阅读(39)  评论(0编辑  收藏  举报