DP-记录

DP记录

四字键盘

在这里插入图片描述

即A,Crtl+A,Crtl+C,Crtl+V四种键盘,使用它们在一个啥也没有的空界面上在指定的N次操作下得到最多的字符,上次笔试遇到的打字店老板题目是类似的,只不过他把Crtl和后键分开了。
部分内容取自labuladong:
https://labuladong.gitbook.io/algo/dong-tai-gui-hua-xi-lie/dong-tai-gui-hua-zhi-si-jian-jian-pan#di-er-zhong-si-lu

对于不同的DP状态定义有不同的解法

对于不同的DP状态定义有不同的解法,当然其时间、空间复杂度也不相同;这道题有两种dp状态的定义方法:

方法1:传统方法,暴力列举所有状态

即dp[i][j][k] ;这里i= 剩余操作数;j = 屏幕中已有的字符个数; k = 剪贴板中的字符数;这种定义好在方便想出,构造也比较简单,状态之间的转移也很容易获得;Base case也是很容易得到的;

//base case
dp[0][j][k] = j;

状态转移

dp[i][j][k] = max(dp[i-1][j+1][k],dp[i-1][j+k][k],dp[i-2][j][k]);

这个方法的时间复杂度是n^3×函数复杂度;

方法2:“贪心”+dp

我们可以思考一下后想到,或者从N=1,到N=20试一试,发现N较小时,单个打字符是比较划算的,在N较大时,使用C+V是比较划算的。所以要将这两个进行比较,取其最大者。重新定义动态规划dp的定义:
dp【i】= 使用i此操作能获得的最大字符数
此时的base case
dp[0] = 0;
dp[1] = 1;
状态转移方法:假设从j开始粘贴字符了,那么,第j-2次操作为C+A,j-1次操作为C+C,第j次就是C+V了。

    for (int i = 1; i <= N; i++) {
        // 按 A 键
        dp[i] = dp[i - 1] + 1;
        for (int j = 2; j < i; j++) {
            // 全选 & 复制 dp[j-2],连续粘贴 i - j 次
            // 屏幕上共 dp[j - 2] * (i - j + 1) 个 A
            dp[i] = Math.max(dp[i], dp[j - 2] * (i - j + 1));
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值