【DBSDFZOJ 4460】666(DP)

Description

小 π 假期在家无聊,打开了某弹幕直播网站。
突然,有一个精彩的镜头。
小 π 看到了满屏的 6,其中,有 666、也有 666666、也有 6666666666 …
小 π 也想发个弹幕,他打算发 n 个 6。
然而当他按下第一个 6 时,键盘上 6 的键坏了。
这时,弹幕框里只有 1 个 6。
键盘坏了什么的不要紧,先把弹幕发了才是正事。
于是小 π 打算用复制粘贴这类操作来生成这 n 个 6。
具体的说,小 π 电脑的操作系统有唯一的一块剪贴板,初始为空,现在小π 一共有三种操作:
第 1 种操作,全选然后复制。这样会把剪贴板里的内容设置为当前弹幕框内内容。
第 2 种操作,粘贴。会把剪贴板中的内容连接到弹幕框现有的内容后面。
第 3 种操作,backspace。会把在当前弹幕框中删除一个 6。
小 π 很好奇现在生成想要的 n 个 6 至少需要多少次操作,来找到了学信息学竞赛的你。
注意本题时间限制1s

Input

一行一个整数 n。

Output

一行一个整数 ans,表示最少操作次数。

Sample Input 1

0

Sample Output 1

1

Sample Input 2

3

Sample Output 2

3

Data Constraint

其中 6% 的数据,n=2^k,k 为正整数。
其中 24% 的数据,n≤1000。
其中 20% 的数据,内存扩充至768MB。
其中 20% 的数据,时间扩充到3s。
其中 30% 的数据,无特殊限制。
所有数据存在一种划分方法,使得上述范围两两没有交集。
对于 100% 的数据,0≤n≤1000000。

解题思路

考虑dp,f[i]代表从1到i最少需要走几步。状态转移有两种情况,一种是退格,一种是翻倍。可以证明用f[i+j]+j更新f[i]时,j至多需要枚举到3。

代码
#include<bits/stdc++.h>
using namespace std;
int n,f[1000005];
int main(){
    scanf("%d",&n);
    if(!n)  {printf("1");return 0;}
    for(int i=1;i<=n+3;++i)     f[i]=i;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=3;++j)       f[i]=min(f[i],f[i+j]+j);
        for(int j=2;i*j<=n+3;++j)   f[i*j]=min(f[i*j],f[i]+j);
    }
    printf("%d",f[n]);
}

感谢Dilhao大佬的讲解及提示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zP1nG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值