dp
DP
用于解决某些问题,可以由某一个状态 弄到下一个状态
例题:
XCPC Description 2020年12月13日,Jiang,Ying和Song组队报名参加了XCPC程序设计竞赛。赛前他们约定,Jiang写最前面的题,Ying写 中间的题,Song写最后的题,每个人写的题都是连续的(比如总共5题,Jiang写1、2、3,Ying写4,Song写5)。 比赛开始时,三人手中各有k1, k2, k3道题,但题号是乱的。现在他们需要把一些题转交给其他人, 使得最终每个人手中的题符合赛前约定。最终可能有人一题不写。求最少转交题目次数。 Input 第一行3个整数 k1, k2, k3 ( 1 \leq k1, k2, k3 \leq 2 * 10^5)(1≤k1,k2,k3≤2∗10 5 ) 第二行k1个整数,表示Jiang一开始拿到的k1道题 第三行k2个整数,表示Ying一开始拿到的k2道题 第四行k3个整数,表示Song一开始拿到的k3道题 保证每个题号各不相同且位于[1, k1+k2+k3]之间 Output 一行一个整数,表示最少转交题目次数。 Sample Input 1 2 1 3 5 6 4 3 1 2 Sample Output 1 3 Hint 样例解释:把第4、5、6题都交给第三个人。
方法:
3个人编号0、1、2 用problem[i]数组表示第i个问题一开始在哪个人手中。 设二维数组dp[i][j]表示第i个人做第j题时,前面1-j题总共要转交几次。 那么 dp[0][i] = dp[0][i - 1] + (problem[i] != 0); dp[1][i] = min(dp[0][i-1], dp[1][i-1]) + (problem[i] != 1); dp[2][i] = min(dp[0][i-1], dp[1][i-1], dp[2][i-1]) + (problem[i] != 2);