lc650

class Solution {
    public int minSteps(int n) {
        int[] dp=new int[n+1];
        dp[0]=0;
        for(int i=1;i<=n;i++){
            dp[i]=i;
            for(int k=1;k<n/2;k++){
                if(i%k==0){
                    dp[i]=Math.min(dp[i],dp[k]+(i/k));
                }
            }
        }
        return n==1?0:dp[n];

    }
}

用dp做,得到长度为i的字符串操作次数最长是i次,但实际上可以优化,比如dp[8]可以用dp[2]加上8/2(复制一次,粘贴3次)或者dp[4]加上8/4 那么每计算一个dp[i]就从头开始遍历,不断找到最小值。
方法比较笨,是第一时间想到的,注意n=1的情况

优化版本来了,考虑素数和的情况可以进行优化:

class Solution {
    public int minSteps(int n) {
        if(n==1) return 0;
        int[] dp=new int[n+1];
        dp[0]=0;
        dp[1]=0;
        int h=(int)Math.sqrt(n);
        for(int i=2;i<=n;i++){
            dp[i]=i;
            for(int k=2;k<=h;k++){
                if(i%k==0){
                    dp[i]=dp[k]+dp[i/k];
                    break;
                }
            }
        }
        return dp[n];

    }
}

找到第一个可以被i整除的素数就返回,dp[i]的结果一定是i所能被分解的素数和的形式。

原文地址:https://www.cnblogs.com/ljf-0/p/13892171.html